<?php
//framework created by NETsolutions Asia
//usage without NETsolutions Asia's permission is forbidden

//TODO when click edit item and click save header change into ADD ITEM instead of UPDATE ITEM
//FORMS LIBRARY
require_once(PATH.'lib/fw/search.php');
require_once(PATH.'lib/fw/files.php');
require_once(PATH.'lib/fw/entities.php');
require_once(PATH.'lib/fw/settings.php');
require_once(PATH.'lib/fw/include.php');
require_once(PATH.'lib/fw/table.php');
require_once(PATH.'lib/fw/fields.php');
require_once(PATH.'lib/fw/export.php');

if (FCK == 1) {
	require_once(PATH.'lib/editor/fckeditor/fckeditor.php');
}
if (FPDF == 1) {
	require_once(PATH.'lib/fpdf/fpdf.php');
}

//call function without required permission
if ($_REQUEST['fajax'] == 1) {
	//TODO all fw_ contains @ framework_inc.php
	if (file_exists(PATH . 'modules/' . $_REQUEST[MAIN_OPTION] . '.php')) {
		require_once(PATH . 'modules/' . $_REQUEST[MAIN_OPTION] . '.php');
	}

	$f = PREFIX . $_REQUEST[MAIN_OPTION];
	$f2 = 'fw_' . $_REQUEST[MAIN_OPTION];

	if ($_REQUEST['view']) {
		$f .= '_' . $_REQUEST['view'];
		$f2 .= '_' . $_REQUEST['view'];
	}

	if (function_exists($f)) {
		echo $f();
	} else if (function_exists($f2)) {
		echo $f2();
	} else {
		echo $f.' - '.$f2;
	}
	exit;
}

/**
 * set update query 
 * use for add new and save item
 * @return query string
 * */
function fw_action_update($basics, $fields, $post, $log_change = '0') {
	global $db;
	$js_separate = CALENDAR_JS_SEPARATE;
	$lq = 0;
	$qry = 'UPDATE `' . $basics['table'] . '` SET ';
	foreach ($fields as $ky => $vl) {
		$multi = 0;
		//check if we have multiple item ('type' => 'C,M,')
		$multiQueries = '';
		if (is_array($vl['multi'])) {
			$multiQueries = $vl['multi']['multi'];
		}
		if ($multiQueries != '') {
			$multi = 1;
		}

		//skip headers and fields which can have to be skiped
		//TODO skip readonly 
		//skip displayonly
		if ($vl['type'] != 'H' && $vl['skip'] != 1 && $vl['readonly'] != 1 && $vl['displayonly'] != 1) {
			//for multi value
			if ($multi == 1) {
				//"Z" keep multi value in same table 
				//separate with ":"
				if ($multiQueries == 'Z') {
					$tmp = '';
					$separ = 0;
					if (is_array($post[$ky])) {
						foreach ($post[$ky] as $xvl) {
							if ($xvl != '') {
								$tmp .= $xvl . ':';
							}
						}
						$post[$ky] = ':' . $tmp;
					}
					$po[$ky] = $post[$ky];
					$qry .= '`'.$ky.'`=' . intoDB($post[$ky], $vl['type']);
				} else {
				//"X" keep multi value in other table
				//not specific field and not checkbox type
					if ($vl['multi']['spec'] != '' && $vl['type'] != 'checkbox') {
						//"multi file" upload
						if ($vl['type'] == 'FM') {
							$default = $vl['default'];
							$old = $_POST[$ky.'_files'];
							$update = $_FILES[$ky.'_Old'];
							$new = $_FILES[$ky.'_new'];
							$result = array();
							$path = str_replace('{id}', $basics['id'], $vl['param2']['bigl']);
							if (count($default) > 0) {
								if (count($old) > 0) {
									$result = array_diff_key($default, $old);
								} else {
									$result = $default;
								}
							}

							if (is_array($result) && count($result) > 0) {
								foreach ($result as $id_k => $val) {
									$xqry = $vl['multi']['qry_del'] . $id_k;
									$db->Execute($xqry, 'fw');
									unlink($path . $id_k . '.' . $val);
								}
							}

							if (count($update) > 0) {
								foreach ($update['name'] as $k => $v) {
									if ($v != '') {
										$xqry = $vl['multi']['qry_del'].$k;
										$db->Execute($xqry,'fw');
										$add_gallery['update'][$k]['name'] = $update['name'][$k];
										$add_gallery['update'][$k]['size'] = $update['size'][$k];
										$add_gallery['update'][$k]['tmp_name'] = $update['tmp_name'][$k];
									}
								}
							}

							if (count($new['name']) > 0) {
								$j = 0;
								for ($i = 0; $i < count($new['name']); $i++) {
									if ($new['name'][$i] != '') {
										$j = $j + 1;
										$add_gallery['new'][$j]['name'] = $new['name'][$i];
										$add_gallery['new'][$j]['size'] = $new['size'][$i];
										$add_gallery['new'][$j]['tmp_name'] = $new['tmp_name'][$i];
									}
								}
							}

							if (count($add_gallery) > 0) {
								if (is_array($add_gallery['new']) && is_array($add_gallery['update'])) {
									$new_gallery = array_merge($add_gallery['update'], $add_gallery['new']);
								} else if (is_array($add_gallery['new'])) {
									$new_gallery = $add_gallery['new'];
								} else if (is_array($add_gallery['update'])) {
									$new_gallery = $add_gallery['update'];
								}

								$par = $vl['param2'];
								//set default values if empty
								if (!isset($par['bigd'])) {
									$par['bigd'] = '';
								}
								if (!isset($par['bigl'])) {
									$par['bigl'] = '';
								} else {
									$par['bigl'] = str_replace('{id}', $basics['id'], $par['bigl']);
								}
								if (!isset($par['info'])) {
									$par['info'] = '';
								}
								if (!isset($par['mini'])) {
									$par['mini'] = 0;
								}
								if (!isset($par['smld'])) {
									$par['smld'] = '';
								}
								if (!isset($par['ratio'])) {
									$par['ratio'] = 1;
								}
								if (!isset($_FILES[$ky.'_s'])) {
									$_FILES[$ky.'_s'] = '';
								}

								if (!is_dir($par['bigl'])) {
									mkdir($par['bigl'], 0777);
								}
								$sml_link = '';
								$sml_ext = '';

								foreach ($new_gallery as $k => $gallery) {
									$big_ext = strtolower(substr($gallery['name'], strrpos($gallery['name'], '.') + 1));
									if ($par['name'] == 'E') {
										$id = '';
										$val = $big_ext;
										$xqry = $vl['multi']['qry_ins'];
										$xqry = str_replace('{id}', (int)$basics['id'], $xqry);
										$xqry = str_replace('{value}', intoDB($val, 'I'), $xqry);
										$db->Execute($xqry, 'fw');

										$xqry = $vl['multi']['qry_get_last'];
										$id = $db->GetOne($xqry, 'fw');
										$name = $id.'.'.$big_ext;//use id for file name
									}
									$big_link = $par['bigl'] . $name;
									file_upl($big_link, $gallery, $big_ext, $par['bigd'], $vl['values'], $par['mini'], $sml_link, $_FILES[$ky.'_s']);
								}
							}
						} else {
							//multi pattern fields
							if ($vl['type'] == 'pattern_multi') {
								if ($post['opt1'] == 'add') {
									unset($vl['default']);
								}
								if ($vl['pattern']) {
									$add_arr = array();
									$update_arr = array();
									$result = array();
									$cn_f = count($vl['pattern']);
									foreach ($vl['pattern'] as $k => $v) {
										$default = $vl['default'];
										$old = $_POST[$k.'_Old'];
										$new = $_POST[$k];
										if (count($vl['default']) > 0) {
											if (count($old) > 0) {
												$result = array_diff_key($default, $old);
											} else {
												$result = $default;
											}
										}
										if (count($old) > 0) {
											foreach ($old as $id_k => $val) {
												$update_arr[$id_k][$k] = $val;
											}
										}
										if (count($new) > 1) {
											foreach ($new as $k_n => $val) {
												if (trim($val) == '') {
													++$ck_new[$k_n];
												}
												$add_arr[$k_n][$k] = $val;
											}
										}
									}
									//delete
									if ($result) {
										foreach ($result as $k => $v) {
											$xqry = $vl['multi']['qry_del'].$k;
											$db->Execute($xqry, 'fw');
										}
									}

									if ($add_arr) {
										foreach ($add_arr as $k => $v) {
											if ($k > 0 && $ck_new[$k] <= $cn_f) {
												$multi_pattern = '';
												$multi_value = '';
												$j = 0;
												$check_val = 0;
												$req = 0;

												foreach ($v as $k2 => $v2) {
													if ($vl['pattern'][$k2]['req'] == 1 && $v2 == '') {
														$req = 1;
													}

													++$j;
													if ($j > 1) {
														$multi_pattern .= ', ';
														$multi_value .= ', ';
													}

													$multi_pattern .= $k2;
													$multi_value .= SQL('%s', $v2);
													if (trim($v2) == '') {
														++$check_val;
													}
												}

												if ($check_val != $j && $req == 0) {
													$xqry = $vl['multi']['qry_ins'];
													$xqry = str_replace('{id}', $basics['id'], $xqry);
													$xqry = str_replace('{multi_pattern}', $multi_pattern, $xqry);
													$xqry = str_replace('{multi_value}', $multi_value, $xqry);
													$db->Execute($xqry, 'fw');
												}
											}
										}
									}
									//update
									if ($update_arr) {
										foreach ($update_arr as $k => $v) {
											$j = 0;
											$patern_multi = '';
											$req = 0;
											foreach ($v as $k2 => $v2) {
												if ($vl['pattern'][$k2]['req'] == 1 && $v2 == '') {
													$req = 1;
												}
												++$j;
												if ($j > 1) {
													$patern_multi .= ', ';
												}
												$patern_multi .= SQL($k2.'=%s', $v2);//$k2.'="'.$v2.'"';
											}
											$xqry = $vl['multi']['qry_upd'];
											$xqry = str_replace('{id}', $k, $xqry);
											$xqry = str_replace('{patern_multi}', $patern_multi, $xqry);
											if ($req == 0) {
												$db->Execute($xqry, 'fw');
											}
										}
									}
								}
							} else {
								$default = $vl['default'];
								$old = $_POST[$ky.'_Old'];
								$new = $_POST[$ky];
								if (count($vl['default']) > 0) {
									if (count($old) > 0) {
										$result = array_diff_key($default, $old);
									}
								}
								if (count($result) > 0) {
									foreach ($result as $id_k => $val) {
										$xqry = $vl['multi']['qry_del'].$id_k;
										$db->Execute($xqry, 'fw');
									}
								}
								if (count($old) > 0) {
									foreach ($old as $id_k => $val) {
										$xqry = $vl['multi']['qry_upd'];
										$xqry = str_replace('{id}', $id_k, $xqry);
										if ($vl['multi']['info_modify'] == 1) {
											$xqry = str_replace('{value}', intoDB($val, 'I').', updated=NOW(), updated_by='.$_SESSION[SESSION_L], $xqry);
										} else {
											$xqry = str_replace('{value}', intoDB($val, 'I'), $xqry);
										}
										$db->Execute($xqry, 'fw');
									}
								}
								if (count($new) > 1) {
									foreach ($new as $k => $val) {
										if ($val != '') {
											$xqry = $vl['multi']['qry_ins'];
											$xqry = str_replace('{id}', $basics['id'], $xqry);
											$xqry = str_replace('{value}', intoDB($val, 'I'), $xqry);

											$db->Execute($xqry, 'fw');
											$id_item = $db->Insert_ID();

											if ($vl['multi']['info_modify'] == 1) {
												$sql = 'UPDATE '.$vl['multi']['qry_tab'].' SET added=NOW(), added_by='.$_SESSION[SESSION_L].', updated=NOW(), updated_by='.$_SESSION[SESSION_L].' WHERE '.$vl['multi']['spec'].'='.$id_item;
												$db->Execute($sql, 'fw');
											}
										}
									}
								}
							}
						}
					} else {
						$xqry = $vl['multi']['qry_del'] . $basics['id'];
						$db->Execute($xqry, 'fw');
						//type "time range"
						if ($vl['type'] == 'TRM') {
							if (is_array($post[$ky.'_from'])) {
								foreach ($post[$ky.'_from'] as $k => $xvl) {
									if ($k != 0) {
										if ($xvl == '00:00') {
											$xvl = NULL;
										} else {
											$xvl = $xvl.':00';
										}
										if ($post[$ky.'_to'][$k] == '00:00') {
											$post[$ky.'_to'][$k] = NULL;
										} else {
											$post[$ky.'_to'][$k] = $post[$ky.'_to'][$k].':00';
										}
										$xqry = $vl['multi']['qry_ins'];
										//no need where cond
										$xqry = str_replace('{id}', (int)$basics['id'], $xqry);
										$xqry = str_replace('{value}', intoDB($xvl).','.intoDB($post[$ky.'_to'][$k]), $xqry);
										$db->Execute($xqry, 'fw');
									}
								}
							}
						} else if ($vl['type'] == 'pattern_multi') {
							if ($vl['pattern']) {
								$add_arr = array();
								$cn_f = count($vl['pattern']);
								foreach ($vl['pattern'] as $k => $v) {
									$new = $_POST[$k];
									if (count($new) > 1) {
										foreach ($new as $k_n => $val) {
											if (trim($val) == '') {
												++$ck_new[$k_n];
											}
											$add_arr[$k_n][$k] = $val;
										}
									}
								}
								//delete
								if ($result) {
									foreach ($result as $k => $v) {
										$xqry = $vl['multi']['qry_del'].$k;
										$db->Execute($xqry, 'fw');
									}
								}
								if ($add_arr) {
									foreach ($add_arr as $k => $v) {
										if ($k > 0 && $ck_new[$k] <= $cn_f) {
											$multi_pattern = '';
											$multi_value = '';
											$j = 0;
											$check_val = 0;
											$req = 0;
		
											foreach ($v as $k2 => $v2) {
												if ($vl['pattern'][$k2]['req'] == 1 && $v2 == '') {
													$req = 1;
												}
		
												++$j;
												if ($j > 1) {
													$multi_pattern .= ', ';
													$multi_value .= ', ';
												}
												if ($vl['pattern'][$k2]['type'] == 'money') {
													$multi_pattern .= $k2;
													$multi_value .= SQL('%f', $v2);
													if(!isset($vl['pattern'][$k2]['currency'])) {
														$multi_pattern .= ','.$k2.'_currency';
														$multi_value .= SQL(',%s', $_POST[$k2.'_currency'][$k]);
													}	
												} else {
													$multi_pattern .= $k2;
													$multi_value .= SQL('%s', $v2);
												}

												if (trim($v2) == '') {
													++$check_val;
												}
											}
		
											if ($check_val != $j && $req == 0) {
												$xqry = $vl['multi']['qry_ins'];
												$xqry = str_replace('{id}', $basics['id'], $xqry);
												$xqry = str_replace('{multi_pattern}', $multi_pattern, $xqry);
												$xqry = str_replace('{value}', $multi_value, $xqry);
												$db->Execute($xqry, 'fw');
											}
										}
									}
								}
							}
						} else {
							$cache_entity = '';
							if (is_array($post[$ky])) {
								$cache_entity = ':'.implode(':', $post[$ky]).':';
								foreach ($post[$ky] as $k => $xvl) {
									if ($xvl != '') {
										$xqry = $vl['multi']['qry_ins'];
										$xqry = str_replace('{id}', (int)$basics['id'], $xqry);
										$xqry = str_replace('{value}', intoDB($xvl, 'I'), $xqry);
										$db->Execute($xqry, 'fw');
									}
								}
							}
							//update to main table
							$sql = 'UPDATE ' . $basics['table'] . ' SET ' . $ky . '_cache="'.$cache_entity.'" WHERE ' . $basics['key'] . '=' . $basics['id'];
							$db->Execute($sql);
						}
					}
				}
			} else {
				//TODO add post param
				if ($vl['function_db'] != '') {
					if (function_exists($vl['function_db'])) {
						$po[$ky] = $vl['function_db']($post[$ky]);
						$qry .= '`'.$ky.'`="'.$vl['function_db']($post[$ky]).'"';
					} else {
						$po[$ky] = $post[$ky];
						$qry .= '`'.$ky.'`='.intoDB($post[$ky], $vl['type']);
					}
					//upload file
				} else {
					$cf_name = 'form_' . $vl['type'];
					if (function_exists($cf_name)) {
						if ($vl['type'] == 'file') {
							$rf = $cf_name($ky, $vl, $link, 'update', $post, $basics);//param not same , add action param
						} else {
							$rf = $cf_name($ky, $vl, 'update', $post);
						}
					} else {
						$rf = $cf_name.'...';
					}
					$po .= $rf['po'];
					$qry .= $rf['qry'];
				}
			}
		} else if (($vl['skip'] == 1 && $vl['type'] != 'H') || $vl['type'] == 'E') {//run custom function
			//TODO check if ($basics['log_removed'] == 2)
			if ($vl['type'] == 'E') {
				$f = PREFIX.$ky;
				if (function_exists($f)) {
					$im = $f($vl, 'action', $basics['id']);
					if (is_array($im)) {
						if ($im['pos']) {
							foreach ($im['pos'] as $kpos => $vpos) {
								$po[$kpos] = $vpos;
							}
						}
						$qry .= $im['sql'];
					} else {
						$qry .= $im;
					}
				}
			}
		}
		if ($vl['readonly'] != 1 && $vl['displayonly'] != 1 &&
			$vl['type'] != 'file' &&
			$vl['type'] != 'password' && $vl['type'] != 'head' &&
			$vl['type'] != 'E' && $vl['type'] != 'EM' && $vl['type'] != 'SP'
			&& $vl['skip'] != 1 && $vl['type'] != 'pattern_multi' && $vl['multi']['multi'] != 'X') {
			$qry .= ', ';
		}
	}
	if ($log_change == 1) {
		return $po;
	}
	//pass and compare -> get old values
	if ($basics['positions'] == 1 && !$post['opt2']) {
		$qry .= ' `positions`=' . $post['positions'];
	}
	if ($basics['log_updated']) {
		$qry .= ' updated=NOW(), updated_by=' . $_SESSION[SESSION_L];
	}
	if ($basics['sql_updated']) {
		$qry .= $basics['sql_updated'];
	}
	$qry .= ' WHERE `' . $basics['key'] . '`=' . (int)$basics['id'];
	//extra condition for update query
	if ($basics['query_req']) {
		$qry .= ' AND ' . $basics['query_req'];
	}
	return $qry;
}

/**
 * for remove item, if set log_removed .. updated, removed will be set
 * @param $basics
 * @param $fields
 * @return
 */
function fw_action_remove($basics, $fields){
	global $db;
	if ($basics['log_removed'] == 1) {
		$qry = SQL('UPDATE `' . $basics['table'] . '`
		SET `removed`=NOW(), `removed_by`=%d, `updated`=NOW(), `updated_by`=%d
		WHERE `'.$basics['key'].'`=%d', $_SESSION[SESSION_L], $_SESSION[SESSION_L], $basics['id']);
	} else {
		foreach ($fields as $key => $inf) {
			if ($inf['type'] == 'file') {
				if ($inf['param2']['name'] == 'E') {
					$file_name = $basics['id'].'.'.$inf['default']['file'];
				} else if ($inf['param2']['name'] == 'F') {
					$link = $_POST[$inf['param2']['fields']].'.'.$inf['default']['file'];
				} else if ($inf['param2']['name'] == 'N') {
					$file_name = $basics['id'].'_'.$key.'.'.$inf['default']['file'];
				} else if ($inf['param2']['name'] == 'R') {
					$file_name = $inf['default']['file'];
				}

				if ($inf['param2']['smll']) {
					$unl = $inf['param2']['smll'] . $file_name;
					//delete file
					unlink($unl);
				}
				if ($inf['param2']['bigl']) {
					$unl = $inf['param2']['bigl'] . $file_name;
					//delete file
					unlink($unl);
				}
			}
		}
		$qry = 'DELETE FROM `'.$basics['table'].'` WHERE `'.$basics['key'].'`="'.$basics['id'].'"';
	}

	if ($basics['query_req']) {
		$qry .= ' AND '.$basics['query_req'];
	}

	if ($db->Execute($qry, 'fw')) {
		return 1;
	} else {
		return 0;
	}
}

/**
 * need to remove to field.php
 * @param $basics
 * @param $fields
 * @param $post
 * @return unknown_type
 */
function fw_data_validate($basics, $fields, $post){
	global $db, $global_config;
	$errs = array();
	foreach ($fields as $ky => $vl) {
		if ($vl['skip'] != 1) {
			if ($vl['type'] == 'file') {
				$file_upload = $_FILES[$ky];
				if ($file_upload['size'] > 0) {
					$extensions = array_keys($global_config['system']['ext_allow']);
					$ext = fw_file_extension($file_upload['name']);

					if (!is_array($extensions)) {
						$errs['file_ext'][] = $vl['head'];
					} else if (!in_array($ext,$extensions)) {
						$errs['file_ext'][] = $vl['head'];
					}
				}
			}

			if ($vl['req'] == 1 && $vl['displayonly'] != 1) {
				if ($vl['type'] == 'P') {
					1;
				} else {
					$functions = 'form_'.$vl['type'];
					if (function_exists($functions)) {
						if ($vl['type'] == 'file') {
							if ($key = $functions($ky, $vl, '', 'validate', $post, $basics)) {
								$errs['req'][] = $fields[$key]['head'];
							}
						} else {
							if ($key = $functions($ky, $vl, 'validate', $post)) {
								$errs['req'][] = $fields[$key]['head'];
							}
						}
					}
					//checked:
					//input,radio,checkbox,time_range,money,date,
					//email,file,lookup,number,password,phone,select,textarea,website (condition same input)
				}
			}
			if ($vl['unique'] == 1) {
				if ($basics['log_removed'] == 1) {
					$cond_add = ' AND (removed_by=0 OR removed_by is NULL)';
				}
				foreach ($fields as $k => $v) {
					if ($v['unique'] == 1) {
						$cond = '';
						$qry = 'SELECT COUNT('.$k.')
						FROM '.$basics['table'].'
						WHERE '.$k.'="'.$post[$k].'" ';
						if ($post['opt2']) {
							if ($basics['id'] > 0) {
								$qry .= ' AND '.$basics['key'].' != "'.(int)$basics['id'].'" ';
							}
						}

						if (isset($v['unique_cond'])) {
							$cond_add .= ' AND ' . $v['unique_second'] . '=' . $post[$v['unique_second']];
						}

						$qry .= $basics['unique_cond'] . $v['unique_cond'] . $cond_add;
						if ($db->GetOne($qry) > 0) {
							$unique_list[$fields[$k]['head']] = 1;
						}
					}
				}
			}
		} else {
			if ($vl['req'] == 1) {
				if ($vl['type'] == 'E') {
					$f = PREFIX.$ky;
				}
				if (function_exists($f)) {
					$er = $f($vl, 'validate', $basics['id']);
					if ($er == 1) {
						$errs['req'][] = $vl['head'];
					}
				}
			}
		}
	}

	if ($unique_list) {
		$errs['unique'] = array_keys($unique_list); //add to this error array which you pass;
	}

	if (count($errs) > 0) {
		$ok = 0;
	} else {
		$fn = PREFIX.$_REQUEST['mod'].'_'.$_REQUEST['view'].'_validate';
		if (function_exists($fn)) {
			$validate_info = $fn('action', $basics['id']);
			$ok = $validate_info['ok'];
			$errs['other'] = $validate_info['errs'];
		} else {
			$ok = 1;
		}
	}
	return array($ok, $errs);
}

function fw_data_cleanup2(&$table, $basics){
	$inf['table']['default_sort'] = array(
		'by' => $basics['table'].'.'.$basics['key'],
		'order' => 'ASC',
		'page' => '0',
		'limit' => $_SESSION[SESSION_A]['result_per_page']
	);

	$inf['table']['headers'] = array(
		'js' => '1',
		//'h'=>'',
		//'width'=>'',
	);

	$inf['table']['search_result_options'] = array(
		'edit',
		'duplicate',
		'delete'
	);

	foreach ($inf['table'] as $k => $v) {
		if ($table[$k] == '' || !isset($table[$k])) {
			$table[$k] = $v;
		} else {
			if ($v) {
				foreach ($v as $k2 => $v2) {
					if ($table[$k][$k2] == '' || !isset($table[$k][$k2])) {
						$table[$k][$k2] = $v2;
					}
				}
			}
		}
	}
}

/**
 *
 * @param $fields
 * @param $basics
 * @return unknown_type
 */
function fw_data_cleanup($fields, $basics) {
	if (is_array($fields) && count($fields) > 0) {
		//if alias is set save its values into full name
		$aliases = array(
			'T' => 'type',
			'H' => 'head',
			'R' => 'req',
			'D' => 'default',
			'V' => 'values',
			'P1' => 'param1',
			'P2' => 'param2',
			'RO' => 'readonly',
			'S' => 'search',
			'ST' => 'search_type',
			'SH' => 'search_head',
			'SP1' => 'search_param1',
			'SV' => 'search_values',
			'SPC' => 'search_pos_col',
			'SPR' => 'search_pos_row',
			'A' => 'addon',
			'AF' => 'addon_field',
			'I' => 'descr',
			'P' => 'show',
			'X' => 'skip',
			'UC' => 'unique_cond',
			'U' => 'unique',
			'FS' => 'function_show',
			'FD' => 'function_db',
			'Z' => 'zone'
		);

		foreach ($fields as $ky => $vl) {
			foreach ($aliases as $k => $v) {
				if (isset($vl[$k])) {
					$vl[$v] = $vl[$k];
				}
				unset($vl[$k]);
			}

			//default type
			if (!isset($vl['type'])) {
				$vl['type'] = 'input';
			}
			$defaults_type = array(
				'I' => 'input',
				'S' => 'select',
				'R' => 'radio',
				'C' => 'checkbox',
				'T' => 'textarea',
				'D' => 'date',
				'N' => 'number',
				'P' => 'password',
				'F' => 'file',
			);

			if (isset($defaults_type[$vl['type']])) {
				$vl['type'] = $defaults_type[$vl['type']];
			}

			//set default value
			$defaults = array(
				'head' => '',
				'default' => '',
				'req' => '0',
				'values' => '',
				'param1' => '',
				'param2' => '',
				'readonly' => '',
				'search' => '0',
				'search_type' => '',
				'search_head' => '',
				'search_param1' => '',
				'search_values' => '',
				'search_pos_row' => '',
				'search_pos_row' => '',
				'addon' => '',
				'addon_field' => '',
				'descr' => '',
				'show' => '1',
				'multi' => '0',
				'skip' => '0',
				'zone' => '0'
			);

			foreach ($defaults as $k => $v) {
				if (!isset($vl[$k])) {
					$vl[$k] = $v;
				}
			}
			if ($vl['type'] == 'city') {
				if (isset($vl['vhead']['city'])) {
					$vl['head'] = $vl['vhead']['city'];
				}
			}
			if ($vl['type'] == 'I') {
				if (!isset($vl['autocomplete'])) {
					$vl['autocomplete'] = '0';
				}
			}
			if ($vl['type'] == 'number') {
				if (strpos($vl['param1'], '.')) {
					$expl = explode('.', $vl['param1']);
					$vl['param2'] = $expl[0] + $expl[1] + 1;
				} else {
					$vl['param2'] = $vl['param1'];
				}
			} else if ($vl['type'] == 'date' && $vl['param1'] == '') {
				$vl['param1'] = 'Ymd';
			} else if ($vl['type'] == 'file' || $vl['type'] == 'file_multi') {
				$basics['files'] = 1;
			} else if (($vl['type'] == 'checkbox' || $vl['type'] == 'multi' || $vl['type'] == 'file_multi' || $vl['type'] == 'input_multi' || $vl['type'] == 'pattern_multi') && !is_array($vl['multi'])) {
				$vl['multi'] = $vl['param2'];
			} else if ($vl['type'] == 'E' || $vl['type'] == 'SP') {
				$vl['skip'] = 1;
			}
			//set default values for multiple fields
			if ($vl['type'] == 'checkbox' && $vl['multi'] == '') {
				$vl['multi']['multi'] = 'Z';
			}
			if (is_array($vl['multi']) && $vl['multi']['multi'] != 'Z') {
				if (!$vl['multi']['multi']) {
					$vl['multi']['multi'] = 'X';
				}
				if ($vl['type'] == 'TRM') {
					//set query for TRM type $vl['multi']['qry_tab']
					if ($vl['multi']['qry_sel'] == '') {
						$vl['multi']['qry_sel'] = 'SELECT `'.$ky.'_from`,`'.$ky.'_to`
						FROM '.$vl['multi']['qry_tab'].'
						WHERE '.$vl['multi']['qry_col_check'].'={value}';
					}
					if ($vl['multi']['qry_ins'] == '') {
						$vl['multi']['qry_ins'] = 'INSERT INTO '.$vl['multi']['qry_tab'].'(`'.$ky.'_from`,`'.$ky.'_to`,`'.$vl['multi']['qry_col_check'].'`) VALUES({value},{id})';
					}
					if ($vl['multi']['qry_del'] == '') {
						$vl['multi']['qry_del'] = 'DELETE FROM '.$vl['multi']['qry_tab'].' WHERE '.$vl['multi']['qry_col_check'].'=';
					}
				} else {
					if ($vl['multi']['spec'] != '') {
						if ($vl['multi']['qry_get_last'] == '') $vl['multi']['qry_get_last'] = 'SELECT `'.$vl['multi']['spec'].'` FROM '.$vl['multi']['qry_tab'].' ORDER BY `'.$vl['multi']['spec'].'` DESC';

						if ($vl['multi']['log_action'] == 1) {
							if ($vl['multi']['qry_sel'] == '') {
								$vl['multi']['qry_sel'] = 'SELECT `'.$vl['multi']['spec'].'`, '.$vl['multi']['qry_col_value'].'
								FROM '.$vl['multi']['qry_tab'].'
								WHERE `'.$vl['multi']['qry_col_check'].'`={value}
								AND removed IS NULL ORDER BY '.$vl['multi']['spec'];
							}
							if ($vl['multi']['qry_del'] == '') {
								$vl['multi']['qry_del'] = 'UPDATE '.$vl['multi']['qry_tab'].' SET `updated`=NOW(), `updated_by`='.$_SESSION[SESSION_L].', `removed`=NOW(), `removed_by`='.$_SESSION[SESSION_L].' WHERE '.$vl['multi']['spec'].' =';
							}
							if ($vl['type'] != 'pattern_multi') {
								if ($vl['multi']['qry_ins'] == '') {
									$vl['multi']['qry_ins'] = 'INSERT INTO '.$vl['multi']['qry_tab'].'('.$vl['multi']['qry_col_value'].', '.$vl['multi']['qry_col_check'].$vl['multi']['qry_ext_col'].', `added`, `added_by`, `updated`, `updated_by`) VALUES({value}, {id}'.$vl['multi']['qry_ext_val'].',NOW(),'.$_SESSION[SESSION_L].',NOW(),'.$_SESSION[SESSION_L].')';
								}
								if ($vl['multi']['qry_upd'] == '') {
									$vl['multi']['qry_upd'] = 'UPDATE '.$vl['multi']['qry_tab'].' SET `'.$vl['multi']['qry_col_value'].'`={value}, `updated`=NOW(), `updated_by`='.$_SESSION[SESSION_L].' WHERE '.$vl['multi']['spec'].'={id}';
								}
							} else {
								if ($vl['multi']['qry_ins'] == '') {
									$vl['multi']['qry_ins'] = 'INSERT INTO '.$vl['multi']['qry_tab'].'({multi_pattern}, '.$vl['multi']['qry_col_check'].$vl['multi']['qry_ext_col'].', `added`, `added_by`, `updated`, `updated_by`) VALUES({multi_value}, {id}'.$vl['multi']['qry_ext_val'].',NOW(),'.$_SESSION[SESSION_L].',NOW(),'.$_SESSION[SESSION_L].')';
								}
								if ($vl['multi']['qry_upd'] == '') {
									$vl['multi']['qry_upd'] = 'UPDATE '.$vl['multi']['qry_tab'].' SET {patern_multi}, `updated`=NOW(), `updated_by`='.$_SESSION[SESSION_L].' WHERE '.$vl['multi']['spec'].'={id}';
								}
							}
						} else {
							if ($vl['multi']['qry_sel'] == '') {
								$vl['multi']['qry_sel'] = 'SELECT `'.$vl['multi']['spec'].'`, '.$vl['multi']['qry_col_value'].'
								FROM '.$vl['multi']['qry_tab'].'
								WHERE `'.$vl['multi']['qry_col_check'].'`={value}
								ORDER BY '.$vl['multi']['spec'];
							}
							if ($vl['multi']['qry_ins'] == '') {
								$vl['multi']['qry_ins'] = 'INSERT INTO '.$vl['multi']['qry_tab'].'('.$vl['multi']['qry_col_value'].', '.$vl['multi']['qry_col_check'].$vl['multi']['qry_ext_col'].') VALUES({value}, {id}'.$vl['multi']['qry_ext_val'].')';
							}
							if ($vl['multi']['qry_del'] == '') {
								$vl['multi']['qry_del'] = 'DELETE FROM '.$vl['multi']['qry_tab'].' WHERE '.$vl['multi']['spec'].' =';
							}
							if ($vl['multi']['qry_upd'] == '') {
								$vl['multi']['qry_upd'] = 'UPDATE '.$vl['multi']['qry_tab'].' SET `'.$vl['multi']['qry_col_value'].'`={value} WHERE '.$vl['multi']['spec'].'={id}';
							}
						}
					} else {
						if ($vl['multi']['qry_sel'] == '') {
							$vl['multi']['qry_sel'] = 'SELECT '.$vl['multi']['qry_col_value'].'
							FROM '.$vl['multi']['qry_tab'].'
							WHERE '.$vl['multi']['qry_ext_where'].$vl['multi']['qry_col_check'].'={value}';
							if ($vl['multi']['qry_order']) {
								$vl['multi']['qry_sel'] .= ' ORDER BY '.$vl['multi']['qry_order'];
							}
						}
						if ($vl['multi']['qry_del'] == '') {
							$vl['multi']['qry_del'] = 'DELETE FROM '.$vl['multi']['qry_tab'].' WHERE '.$vl['multi']['qry_ext_where'].$vl['multi']['qry_col_check'].'=';
						}
						if ($vl['multi']['qry_ins'] == '') {
							$vl['multi']['qry_ins'] = 'INSERT INTO '.$vl['multi']['qry_tab'].'('.$vl['multi']['qry_col_value'].', '.$vl['multi']['qry_col_check'].$vl['multi']['qry_ext_col'].') VALUES({value}, {id}'.$vl['multi']['qry_ext_val'].')';
						}
					}
				}
			}
			//save changes in files table
			$fields[$ky] = $vl;
		}
	}

	//$basics SET aliases & defaults
	if (is_array($basics) && count($basics) > 0) {
		$aliases = array(
			'O' => 'output',
			'SI' => 'single_item',
			'FA' => 'form_addon',
			'QA' => 'query_add',
			'QAV' => 'query_add_value',
			'QR' => 'query_req',
			'H' => 'header',
			'HE' => 'header_edit',
			'HDQ' => 'inf_del_query',
			'ID' => 'inf_del',
			'IA' => 'inf_add',
			'IU' => 'inf_upd',
			'HL' => 'header_list',
			'LQ' => 'list_query',
			'LQA' => 'list_query_add',
			'LI' => 'list_items',
			'LV' => 'list_values',
			'LS' => 'list_size',
			'LD' => 'list_divider',
			'LDH' => 'list_divider_head',
			'LFB' => 'list_form_buttons',
			'SF' => 'search_form',
			'SM' => 'search_method',
			'SFS' => 'search_form_style',
			'DL' => 'descrL',
			'DR' => 'descrR',
			'DT' => 'descrT',
			'DTR' => 'descrTR',
			'DM' => 'descrM',
			'UC' => 'unique_cond',
			'POST' => 'positions',
			'VSB' => 'visible');

		//FOR check fields visible and positions ...
		foreach ($aliases as $k => $v) {
			if (isset($basics[$k])) {
				$basics[$v] = $basics[$k];
			}
			unset($basics[$k]);
		}

		$defaults = array(
			'editonly' => '0',
			'files_rem' => '1',
			'files' => '0',
			'form_addon' => '',
			'tabinfos' => '',
			'list_divider' => '',
			'search_form_buttons' => '',
			'list_query_add' => '',
			'header_list' => '',
			'descrL' => '',
			'descrR' => '',
			'descrM' => '',
			'descrT' => '',
			'list_size' => '',
			'list_size_width' => '',
			'query_req' => '',
			'query_upd' => '',
			'search_form' => '0',
			'search_form_style' => '2',
			'single_item' => '0',
			'output' => 'N',
			'unique_cond' => '',
			'positions' => '0',
			'visible' => '0',
			'set_log' => '1',
			'set_page_title' => '1',
		);

		if (!$basics['actions']['manage_group']) {
			$defaults['manage_group_set'] = '-1';
		}

		foreach ($defaults as $k => $v) {
			if (!isset($basics[$k])) {
				$basics[$k] = $v;
			}
		}

		if ($basics['set_log'] == 1) {
			if (LOG_CHANGE == 1) {
				$basics['log_change'] = 1;
			}
			if (LOG_ADDED == 1) {
				$basics['log_added'] = 1;
			}
			if (LOG_UPDATED == 1) {
				$basics['log_updated'] = 1;
			}
			if (LOG_REMOVED == 1) {
				$basics['log_removed'] = 1;
			}
		} else if ($basics['set_log'] == 2) {
			if (LOG_CHANGE == 1) {
				$basics['log_change'] = 1;
			}
			if (LOG_ADDED == 1) {
				$basics['log_added'] = 1;
			}
			if (LOG_UPDATED == 1) {
				$basics['log_updated'] = 1;
			}
			if (LOG_REMOVED == 1) {
				$basics['log_removed'] = 2;
			}
		}
	}
	return array($fields, $basics);
}

/**
 * get default value from
 * @param $fields
 * @param $basics
 * @param $row
 * @return fields with default values
 */
function fw_data_get($fields, $basics, $row = ''){
	global $db;
	$items = '';
	//create list of values which we get form database
	if (!$row) {
		//set query
		foreach ($fields as $ky => $vl) {
			//if ($vl['type'] == 'checkbox') print_r($vl);
			$multiQueries = '';
			if (is_array($vl['multi'])) {
				$multiQueries = $vl['multi']['multi'];
			}
			if ($vl['type'] != 'H' && $vl['skip'] != 1 && $multiQueries != 'X' && $vl['type'] != 'TR' && $vl['type'] != 'daterange' && $vl['type'] != 'file') {
				$items .= ', `'.$ky.'`';
			}

			if ($vl['type'] == 'TR') {
				$items .= ', `'.$ky.'_from`, `'.$ky.'_to`';
			} else if ($vl['type'] == 'money') {//MONEY
				if ($vl['currency'] != 0 || !isset($vl['currency'])) {
					$items .= ', `'.$ky.'_currency`';
				}
			} else if ($vl['type'] == 'phone') {
				$items .= ', `'.$ky.'`, `'.$ky.'_ext`';
			} else if ($vl['type'] == 'LU') {
				$items .= ', `'.$ky.'`, `id_'.$ky.'`';
			} else if ($vl['type'] == 'file') {
				if ($_REQUEST['opt'] != 11) {
					if (!is_array($vl['param2'])) {
						$items .= ', `'.$ky.'_updated`, `'.$ky.'_updated_by`';
					}
					$items .= ', `'.$ky.'`';
					if ($vl['param2']['descr'] == 1) {
						$items .= ',`'.$ky.'` , `'.$ky.'_descr`';
					}
				}
			} else if ($vl['type'] == 'city') {
				$items .= ', `'.$ky.'`, `'.$vl['prefix'].'postcode`, `'.$vl['prefix'].'state`';
			} else if ($vl['type'] == 'daterange') {
				$items .= ', `'.$ky.'_from`, `'.$ky.'_to`';
			} else if ($vl['type'] == 'name' && $vl['skip'] != 1) {
				$items .= ', `'.$ky.'_title`, `'.$ky.'_first`, `'.$ky.'_middle`, `'.$ky.'_last`, `'.$ky.'_suffix`, `'.$ky.'_initials`, `'.$ky.'_display`, `'.$ky.'_keep`';
			}
		}

		//for select more fields
		if ($basics['select_fields_add']) {
			$items .= $basics['select_fields_add'];
		}

		//verify
		if ($basics['verify'] == 1) {
			$items .= ', `verified`, `verified_by`';
		}

		//if we want to display added, updated we need to add it to $items
		if ($basics['log_updated'] == 2 || $basics['log_added'] == 2) {
			$items .= ', `added`, `added_by`, `updated`, `updated_by`';
		}
		if ($basics['log_removed'] == 1) {
			$items .= ', `removed`, `removed_by`';
		}

		$qry = 'SELECT `'.$basics['key'].'`'.$items.' FROM `'.$basics['table'].'`';
		$qry .= SQL(' WHERE `'.$basics['key'].'`=%d', $basics['id']);
		//if we have additional SELECT requirement we have to add it
		if ($basics['query_req']) {
			$qry .= ' AND '.$basics['query_req'];
		}
		$row = $db->GetRow($qry, 'fw');
		if ($_REQUEST['opt'] == 5) {
			if ($basics['log_updated'] == 2 || $basics['log_added'] == 2) {
				if (isset($row['updated_by'])) {
					$user_name = $row['added_by'].','.$row['updated_by'];
				} else {
					$user_name = $row['added_by'];
				}
				$sql = str_replace('{in}', $user_name, FRAMEWORK_SQL_USER_LIST);
				$user_li = $db->GetAssoc($sql, 'fw');

				$header_edit = '';
				if (isset($row['added'])) {
					$header_edit .= 'added: '.format_date_time($row['added'], FW_LOG_FORMAT).' ('.$user_li[$row['added_by']].')';
				}
				if (isset($row['updated'])) {
					$header_edit .= '<br />updated: '.format_date_time($row['updated'], FW_LOG_FORMAT).' ('.$user_li[$row['updated_by']].')';
				}
				echo '<div class="show_name">'.$header_edit.'</div>';//TODO this should be returned not echo
			}
		}
	}
	//query not-corect
	if (!is_array($row)) {
		echo $qry.'<br/>';
		die(INF_SURE);
	}

	//update default value with one from DB
	//check select fields -add
	$select_fields_add = $row;
	foreach ($fields as $ky => $vl) {
		unset($select_fields_add[$ky]);
		if ($vl['skip'] != 1) {
			$multiQueries = '';
			if (is_array($vl['multi'])) $multiQueries = $vl['multi']['multi'];
			//X-save data cross table
			if ($multiQueries == 'X') {
				$xqry = $vl['multi']['qry_sel'];
				$xqry = str_replace('{value}', (int)$basics['id'], $xqry);
				if ($vl['type'] == 'TRM') {
					$vl['default'] = $db->GetArray($xqry, 'fw');
				} else {
					if ($vl['multi']['spec'] != '') {
						$vl['default'] = $db->GetAssoc($xqry, 'fw');
					} else {
						if($vl['type'] == 'pattern_multi') {
							$vl['default'] = $db->GetArray($xqry, 'fw');
						} else {
							$vl['default'] = $db->GetCol($xqry, 'fw');
						}
					}
				}
			} else if ($vl['type'] != 'H' && $vl['type'] != 'P') {
				//use predefined function
				if ($vl['function_show'] != '') {
					if (function_exists($vl['function_show'])) {
						$vl['default'] = $vl['function_show']($row[$ky]);
					} else {
						$vl['default'] = $row[$ky];
					}
				} else if ($vl['type'] == 'file') {
					if (is_array($vl['param2'])) {
						$vl['default']['file'] = $row[$ky];
						if ($vl['param2']['name'] == 'F') {
							$vl['default']['fields'] = $row[$vl['param2']['fields']];
						}
						if (!isset($vl['param2']['descr'])) {
							$vl['param2']['descr'] = 0;
						}
						if ($vl['param2']['descr'] == 1) {
							$vl['default']['descr'] = $row[$ky.'_descr'];
						}
					} else {
						$vl['default'][$ky] = $row[$ky];
						$vl['default'][$ky.'_updated'] = $row[$ky.'_updated'];
						$vl['default'][$ky.'_updated_by'] = $row[$ky.'_updated_by'];
					}
				} else if ($vl['type'] == 'TR') {
					$vl['default'] = array($row[$ky.'_from'], $row[$ky.'_to']);
				} else if ($vl['type'] == 'money') {//MONEY
					$vl['default'] = array('money' => $row[$ky], 'currency' => $row[$ky.'_currency']);
				} else if ($vl['type'] == 'phone') {//phone
					$vl['default'] = array('phone' => $row[$ky], 'ext' => $row[$ky.'_ext']);
				} else if ($vl['type'] == 'lookup') {
					$vl['default'] = array($row['id_'.$ky], $row[$ky]);
				} else if ($vl['type'] == 'city') {
					$vl['default'] = array('city' => $row[$ky], 'state' => $row[$vl['prefix'].'state'], 'postcode' => $row[$vl['prefix'].'postcode']);
				} else if ($vl['type'] == 'daterange') {
					if ($row[$ky.'_from'] != $row[$ky.'_to']) {
						$vl['default'] = $row[$ky.'_from'].' to '.$row[$ky.'_to'];
					} elseif ($row[$ky.'_from']) {
						$vl['default'] = $row[$ky.'_from'];
					} else {
						$vl['default'] = '';
					}
				} else if ($vl['type'] == 'name') {
					$vl['default'][$ky] = $row[$ky];
					$vl['default'][$ky.'_first'] = $row[$ky.'_first'];
					$vl['default'][$ky.'_last'] = $row[$ky.'_last'];
					$vl['default'][$ky.'_title'] = $row[$ky.'_title'];
					$vl['default'][$ky.'_middle'] = $row[$ky.'_middle'];
					$vl['default'][$ky.'_suffix'] = $row[$ky.'_suffix'];
					$vl['default'][$ky.'_initials'] = $row[$ky.'_initials'];
					$vl['default'][$ky.'_display'] = $row[$ky.'_display'];
					$vl['default'][$ky.'_keep'] = $row[$ky.'_keep'];
				} else if ($vl['type'] == 'autocomplete') {
					if ($vl['save_name'] == 1) {
						$vl['default']['name'] = $row[$ky];
						$vl['default']['id'] = $row[$ky];
					} else {
						require_once 'modules/' . $vl['entity'] . '.php';
						$fn = PREFIX . $vl['entity'] . '_list';
						if ($vl['list']) {
							$_REQUEST['type'] = $vl['list'];
						}
						if (function_exists($fn) && $row[$ky]) {
							//unset($_REQUEST['type']);
							$tmp = $fn($row[$ky]);
							$tmp_id = array_keys($tmp);
							$id = $tmp_id[0];
							$vl['default']['id'] = $id;
							$vl['default']['name'] = $tmp[$id];
						}
					}
				} else {
					$vl['default'] = $row[$ky];
				}
			}
			//replace values
			$fields[$ky] = $vl;
		} else {
			//check function exits
			$fn = PREFIX.$ky.'_data_get';
			if (function_exists($fn)) {
				$fields[$ky]['default'] = $fn($basics['id']);
			}
		}

		if ($_REQUEST['opt'] == 11) {
			if ($vl['duplicate_info']) {
				$fields[$ky]['default'] = '';
			}
		}
	}
	//for select more fields
	if ($basics['select_fields_add'] && $select_fields_add) {
		foreach ($select_fields_add as $k => $v) {
			$fields[$k] = array('default' => $row[$k], 'skip' => 1);
		}
	}

	//verify
	if ($basics['verify'] == 1) {
		$fields['verified'] = array('default' => $row['verified'], 'skip' => 1);
		$fields['verified_by'] = array('default' => $row['verified_by'], 'skip' => 1);
	}
	if ($row['removed'] && $row['removed_by'] > 0) {
		$fields['item_removed'] = array();
	}
	if (count($row) == 0) {
		$fields['count_row_zero'] = array();
	}

	return $fields;
}

/**
 * add new record, if isset for check query... do return current item
 * @param $basics
 * @param $fields
 * @param $post
 * @return new record
 */
function fw_action_add($basics, $fields, $post){
	global $db, $cm_menu;
	if ($basics['log_added']) {
		$basics['query_add'] .= ', `added`, `added_by`, `updated`, `updated_by`';
		$basics['query_add_value'] .= ', NOW(),'.$_SESSION[SESSION_L].', NOW(),'.$_SESSION[SESSION_L];
	}
	
	//check permission
	$entity_info = gain_entity_get_entity_detail($basics['entity']);
	$entity_check = $entity_info['mod_main'];

	if ($cm_menu['M'][$entity_check]['P'] == 1) {
		$basics['query_add'] .= ', `dept_owner`';
		$basics['query_add_value'] .= ','.$_SESSION[SESSION_A]['department'];
	}
	
	//check fields that we dont want to add new record
	if ($basics['check_query']) {
		$do_not_added = $db->GetOne($basics['check_query'], 'fw');
	}
	if ($do_not_added == '' && $basics['do_not_added'] != 1) {
		$qry = 'INSERT INTO `'.$basics['table'].'`(`'.$basics['key'].'`'.$basics['query_add'].') VALUES(NULL'.$basics['query_add_value'].')';
		$db->Execute($qry, 'fw');
		$basics['id'] = $db->Insert_ID();
		$qry = fw_action_update($basics, $fields, $post);
		
		if ($db->Execute($qry, 'fw')) {
			if ($cm_menu['M'][$entity_check]['P'] == 1) {
				//insert to gain_entity_permission
				$param_qry = array(
					'table' => 'gain_entity_permission',
					'cols' => array(
						'entity', '%s', $basics['entity'],
						'entity_id', '%d', $basics['id'],
						'access_type', '%s', 'D',
						'access_id', '%d', $_SESSION[SESSION_A]['department'],
						'p_view', '%d', 1,
						'p_modify', '%d', 1,
						'p_delete', '%d', 1
					),
				);
				db_query($param_qry);
			}
			return array(1, $basics['id']);
		} else {
			return array(0, $basics['id'], $do_not_added);
		}
	} else {
		return array(0, $basics['id'], $do_not_added);
	}
}

/**
 * return form
 * @param $basics
 * @param $fields
 * @param $post
 * @return unknown_type
 */
function fw_form($basics, $fields, $post){
	$del_opt = '';
	$disabled = '';
	//set confirm
	if ($_REQUEST['ajax'] == '1' || $_REQUEST['link'] == 'edit') {
		$confirm_del = ' onclick="return confirm_word(\'Do you want to delete this record?\')"';
		$del_bnt_name = 'opt4';
	}
	if ($basics['editonly'] != 1) {
		if ($basics['custom_delete_btn']) {
			$del_opt = $basics['custom_delete_btn'];
		} else {
			$del_opt = '<input class="btn medium red awesome btn-delete" name="opt4" type="submit" value="'.INF_DEL.'" '.$confirm_del.' style="float: left;"/>';
		}
	}
//	<button value="submit" name="'.$del_bnt_name.'" class="del_button" '.$confirm_del.'><span>'.INF_DEL.'</span></button>
//	<input class="delete_button" name="'.$del_bnt_name.'" type="submit" value="'.INF_DEL.'" '.$confirm_del.'/> ';
	//	if ($basics['editonly'] == 1) $disabled = 'DISABLED';
	if (WYM == 1) {
		$wymCls = ' wymupdate';
	} else {
		$wymCls = '';
	}
	if ($basics['del_button'] == 1) {
		$del_opt = '';
	}
	if (isset($basics['addon_button'])) {
		$addon_button = $basics['addon_button'];
	}
	if (isset($basics['name_button'])) {
		$name_button = $basics['name_button'];
	} else {
		$name_button = INF_ADD;
	}
	if ($basics['re-action']) {
		foreach ($basics['re-action'] as $k => $v) {
			$re_act_choice[base64_encode($k)] = $v;
			if ($_REQUEST['mod'] == 'settings' || $_REQUEST['mod'] == 'newsletter') {
				if (strstr($k, 'mod='.$_REQUEST['mod'].'&view='. $basics['entity'] . '&link=add') && $_REQUEST['re-act']) {
					$default_re_act = base64_encode($k);
				}
			} else {
				if (strstr($k, 'mod=' . $basics['entity'] . '&link=add') && $_REQUEST['re-act']) {
					$default_re_act = base64_encode($k);
				}
			}
		}
		$options_act = '<span class="fw_re-action_area">'.msg('and').' '.form_select('fw_re-action', array('values' => $re_act_choice, 'default' => $default_re_act, 'req' => 1)).'</span>';
	}
	
	if (isset($_REQUEST['popup_id'])) {
		$action_cancel = ' onclick="closePopup();"';
	} else {
		//set link for cancel
		$link_cancel = explode('&' . $basics['entity'], $basics['op']);
		$link_cancel = explode('&submit_type=json', $link_cancel[0]);
		$detail_link = gain_entity_get_entity_detail($basics['entity'], 'detail_link');
		if ($detail_link == '') {
			$detail_link = 'index.php?mod='.$_REQUEST['mod'];
			if ($_REQUEST['view']) {
				$detail_link .= '&view='.$_REQUEST['view'];
			}
			$detail_link .= '&link=detail&id=';
		}
		$action_cancel = ' onclick="load_page_content(\'' . $detail_link . $basics['id'].'&ajax=1\',\'#items_details\')"';
	}
	$cancel_opt = '<input type="button" value="'.INF_CANCEL.'" class="btn medium gray awesome btn-cancel'.$wymCls.'" name="cancel" '.$addon_button.$action_cancel.'/>';
	if ($basics['cancel_button'] == 1) {
		$cancel_opt = '';
	}
	//TODO
	if ($basics['id'] && !$post['opt11']) {
		$options = '<input type="submit" value="'.INF_SAVE.'" class="btn medium green awesome btn-add'.$wymCls.'" name="opt2" '.$addon_button.' />';
//		if ($_REQUEST['mod'] != 'settings') {
			$options .= $options_act;
//		}
		$options .= ' &nbsp; ' . $cancel_opt . ' &nbsp; ' . $del_opt;
	} else {
		$options = '<input class="btn medium green awesome btn-add'.$wymCls.'" type="submit" name="opt1" value="'.$name_button.'" '.$disabled.$addon_button.'/> '.$options_act;
	}
	if (isset($basics['add_button'])) {
		$options .= $basics['add_button'];
	}
	if (!isset($post['post_form'])) {
		$post['post_form'] = 0;
	}
	$post_form = "\n".'<input type="hidden" name="post_form" value="1"/>';
	$r = $post_form.'<table class="item_form" cellspacing="1" cellpadding="4" id="'.$_REQUEST['op'].'">'."\n";
	foreach ($fields as $key => $inf) {
		if ($inf['readonly'] == 1 || $inf['displayonly'] == 1) {//dont overwrite values of fields which cant be saved anyway
			1;
		} else if ($post['post_form'] == 1) {
			if ($inf['type'] == 'date') {
				if ($inf['values'] == 'number') {
					if ($inf['type'] == 'H') {
						$inf['default'] = $post[$key.'_hour'];
					} elseif ($inf['type'] == 'I') {
						$inf['default'] = $post[$key.'_minute'][0];
					} elseif ($inf['type'] == 'M') {
						$inf['default'] = $post[$key.'_month'];
					} elseif ($inf['type'] == 'D') {
						$inf['default'] = $post[$key.'_day'];
					} elseif ($inf['type'] == 'Y') {
						$inf['default'] = $post[$key.'_year'];
					}
				} else {
					// if field type/values/ is unix then change it into unixtime
					if ($inf['values'] == 'unix') {
						if ($post[$key.'_hour'] == '') {
							$post[$key.'_hour'] = '0';
						}
						if ($post[$key.'_minute'][0] == '') {
							$post[$key.'_minute'][0] = '0';
						}
						if ($post[$key.'_month'] == '') {
							$post[$key.'_month'] = '0';
						}
						if ($post[$key.'_day'] == '') {
							$post[$key.'_day'] = '0';
						}
						if ($post[$key.'_year'] == '') {
							$post[$key.'_year'] = '0';
						}
					} else {
						if ($post[$key.'_hour'] == '') {
							$post[$key.'_hour'] = '00';
						}
						if ($post[$key.'_minute'][0] == '') {
							$post[$key.'_minute'][0] = '00';
						}
						if ($post[$key.'_month'] == '') {
							$post[$key.'_month'] = '00';
						}
						if ($post[$key.'_day'] == '') {
							$post[$key.'_day'] = '00';
						}
						if ($post[$key.'_year'] == '') {
							$post[$key.'_year'] = date('Y');
						}
					}

					if ($inf['values'] == 'unix') {
						$calendar = split($js_separate{0}, $post[$key.'_calendar']);
						if (isset($post[$key.'_calendar'])) {
							if ($post[$key.'_calendar'] != '') {
								$inf['default'] = mktime($post[$key.'_hour'], $post[$key.'_minute'][0], 0, $calendar[1], $calendar[2], $calendar[0]);
							} else {
								$inf['default'] = '';
							}
						} else { //set month day year hour and minute
							if ($post[$key.'_day'] != '0' || $post[$key.'_month'] != '0' || $post[$key.'_year'] != '0') {
								$inf['default'] = mktime($post[$key.'_hour'], $post[$key.'_minute'][0], 0, $post[$key.'_month'], $post[$key.'_day'], $post[$key.'_year']);
							} else {
								$inf['default'] = '';
							}
						}
					}
					if ($inf['values'] == 'datetime') {
						if (isset($post[$key.'_calendar'])) {
							if ($post[$key.'_calendar'] != '') {
								$inf['default'] = $post[$key.'_calendar'].' '.$post[$key.'_hour'].$js_separate{1}.$post[$key.'_minute'][0].$js_separate{1}.'00';
							} else {
								$inf['default'] = '';
							}
						} else { //set month day year hour and minute
							if ($post[$key.'_day'] != '00' || $post[$key.'_month'] != '00' || $post[$key.'_year'] != date('Y')) {
								$inf['default'] = $post[$key.'_year'].$js_separate{0}.$post[$key.'_month'].$js_separate{0}.$post[$key.'_day'].' '.$post[$key.'_hour'].$js_separate{1}.$post[$key.'_minute'][0].$js_separate{1}.'00';
							} else {
								$inf['default'] = '';
							}
						}
					}
					if ($inf['values'] == 'date') {
						if (isset($post[$key.'_calendar'])) {
							if ($post[$key.'_calendar'] != '') {
								$inf['default'] = $post[$key.'_calendar'];
							} else {
								$inf['default'] = '';
							}
						} else { //set month day year hour and minute
							if ($post[$key.'_day'] != '00' || $post[$key.'_month'] != '00' || $post[$key.'_year'] != date('Y')) {
								$inf['default'] = $post[$key.'_year'].$js_separate{0}.$post[$key.'_month'].$js_separate{0}.$post[$key.'_day'];
							} else {
								$inf['default'] = '';
							}
						}
					}
					if ($inf['values'] == 'time') {
						$inf['default'] = $post[$key.'_hour'].$js_separate{1}.$post[$key.'_minute'][0].$js_separate{1}.'00';
					}
				}
			} else {
				//TODO this might require different variable for checking (skip_post_cleanup?)
				if ($inf['skip'] != 1) {
					$inf['default'] = $post[$key];
				}
			}
		}

		//return form single item
		$f = fw_form_item($key, $inf, $basics);

		//set for group action
		if ($inf['type'] == 'head') {
			$check_head[$key] = 1;
		}
		if ($inf['group']) {
			if (is_array($inf['default'])) {
				$def = implode($inf['default'], '');
			} else {
				$def = $inf['default'];
			}
			$check_group[$inf['group']] .= $def;
		}

		if ($basics['view_zone'] > 0) {
			if (!$inf['none_head']) {
				$rz[$inf['zone']] .= $f['head'].$f['field'].$f['foot'];
			}
		}
		$r .= $f['head'].$f['field'].$f['foot'];
	}

	if ($check_head) {
		foreach ($check_head as $key_head => $val) {
			if (isset($check_group[$key_head])) {
				if (trim($check_group[$key_head]) == '') {
					$rep['{{group_hide_'.$key_head.'}}'] = ' hide';
					$cls = 'ui-icon ui-icon-plusthick';
				} else {
					$rep['{{group_hide_'.$key_head.'}}'] = '';
					$cls = 'ui-icon ui-icon-minusthick';
				}
				$rep['{{pattern_group_'.$key_head.'}}'] = '<a href="#showMe" onclick="gain_header_toggle_group(this, \'group_'.$key_head.'\');"><div class="ui-state-default ui-corner-all toggle_ico"><span class="'.$cls.'"></span></div></a> ';
				if ($rz) {
					foreach ($rz as $k => $v) {
						$rz[$k] = str_replace(array_keys($rep), array_values($rep), $v);
					}
				} else {
					$r = str_replace(array_keys($rep), array_values($rep), $r);
				}
			} else {
				$rep['{{pattern_group_'.$key_head.'}}'] = '';
				$rep['{{group_hide_'.$key_head.'}}'] = '';
				if ($rz) {
					foreach ($rz as $k => $v) {
						$rz[$k] = str_replace(array_keys($rep), array_values($rep), $v);
					}
				} else {
					$r = str_replace(array_keys($rep), array_values($rep), $r);
				}
			}
		}
	}

	if ($basics['displayonly'] != 1) {
		$r .= '<tr><td colspan="2" class="fw-form_buttons">'.$options.'</td></tr>'."\n";
	}

	$r .= '</table>'."\n";
	if ($basics['view_zone'] > 0) {
		return array('options' => $post_form . $options, 'form' => $rz);
	}

	if ($basics['single_field'] || $basics['value_only']) {
		$r = $f;
	}

	if ($basics['single_field']) {
		$r .= $post_form;
	}

	return $r;
}

//TODO use?
/**
 * show table listing
 * @param $query
 * @param $basics
 * @return table
 */
function fw_list($query, $basics){
	global $db;
	$r = '';
	$del_opt = '';
	$divide = '';
	$rsl = $db->GetAll($query, 'fw');
	$r .= '
	<table class="fw-items_list ui-corner-all ui-widget fw-table_effect" cellspacing="1" table="'.$basics['table'].'" key="'.$basics['key'].'" cellpadding="4"'.$basics['list_size_width'].'>
	<tr class="ui-state-default"><th>#'.fw_head_list('id').'</th>';
	if ($basics['list_items']) {
		foreach ($basics['list_items'] as $vl) {
			$r .= '<th>'.fw_head_list($vl).'</th>';
		}
	}
	if (!$basics['search_form_buttons']) {
		$basics['search_form_buttons'] = 1;
	}
	if ($basics['search_form_buttons'] == 1) {
		$r .= '<th>'.fw_head_list(INF_OPTIONS).'</th>';
	}
	$r .= '</tr>'."\n";
	$colspan = count($basics['list_items']) + 2;
	if ($basics['list_divider']) {
		$matches = fw_format_item_get($basics['list_divider_head']);
	}
	if ($basics['list_values']) {
		array_unshift($basics['list_values'], '{'.$basics['key'].'}');
	}
	$i = -1;
	if ($basics['log_updated'] == 2 || $basics['log_added'] == 2) {
		foreach ($rsl as $a => $b) {
			if ($basics['log_added'] == 2 && $b['added_by'] > 0) {
				$used_by[$b['added_by']] = 1;
			}
			if ($basics['log_updated'] == 2 && $b['updated_by'] > 0) {
				$used_by[$b['updated_by']] = 1;
			}
		}
		$used_by = implode(',', array_keys($used_by));
		$sql = str_replace('{in}', $used_by, FRAMEWORK_SQL_USER_LIST);
		$used_by = $db->GetAssoc($sql, 'fw');
	}
	if ($rsl) {
		foreach ($rsl as $k => $row) {
			++$i;
			if ($basics['list_divider']) {
				if ($divide != $row[$basics['list_divider']]) {
					$r .= '<tr class="fw-event2"><td colspan="'.$colspan.'">'.fw_format_item_change($basics['list_divider_head'], $matches, $row, $basics['tabinfos']).'</td></tr>';
				}
			}
			$link = FRAMEWORK_URL.$basics['op'].'&amp;id='.$row[$basics['key']].'&amp;opt=';
			if ($row[$basics['key']] == $basics['id']) {
				$class = 'fw-eventA';
			} else {
				$class = 'fw-event'.($i % 2);
			}
			$r .= '<tr class="'.$class.'" item="'.$row[$basics['key']].'">';
			$kl = 0;
			foreach ($basics['list_values'] as $vl) {
				$add = '';
				++$kl;
				if ($kl == 1) {
					$add = '<a name="id'.$row[$basics['key']].'"></a>';
				}
				$matchesX = fw_format_item_get($vl);
				$vl = fw_format_item_change($vl, $matchesX, $row, $basics['tabinfos']);
				$r .= '<td>'.$add.$vl.'</td>';
				$export[$row[$basics['key']]][] = $vl;
			}
			$dup_item = ' <a href="'.FRAMEWORK_URL.$basics['op'].'&id='.$row[$basics['key']].'&opt=11"><img src="'.FRAMEWORK_IMG.'duplicate.png" title="'.INF_DUP.'" alt="'.INF_DUP.'"/></a>';
			if ($basics['search_form_buttons'] == 1) {
				if ($basics['editonly'] != 1) {
					$del_opt = ' <a onClick="usun(\''.$link.'4\',\''.$basics['inf_del_query'].'\'); return false;" href="'.$link.'3#id'.$row[$basics['key']].'"><img style="vertical-align: bottom;" src="'.FRAMEWORK_IMG.'remove.png" alt="'.INF_DEL.'" title="'.INF_DEL.'" /></a>';
				} else {
					$visible = '';
					$dup_item = '';
					$pos	 = '';
				}
				if ($visible) {
					$v = 18;
				}
				if ($dup_item) {
					$d = 18;
				}
				if ($pos) {
					$p = 34;
				}
				$w = 38 + $v + $d + $p;
				if ($basics['log_added'] == 2) {
					$logs_added = ' <img src="im/added.png" alt="added details" title="added: '.format_date_time($row['added'], FW_LOG_FORMAT).'<br/>added by:'.$used_by[$row['added_by']].'"/>';
				}
				if ($basics['log_updated'] == 2) {
					$logs_updated = ' <img src="im/update.png" alt="updated details" title="updated: '.format_date_time($row['updated'], FW_LOG_FORMAT).'<br/>updated by:'.$used_by[$row['updated_by']].'"/>';
				}
				$r .= '<td width="'.$w.'"><a href="'.$link.'5"><img src="'.FRAMEWORK_IMG.'edit.png" alt="'.INF_EDIT.'" title="'.INF_EDIT.'" /></a>'.$del_opt.$visible.$dup_item.$pos.$logs_added.$logs_updated.'</td></tr>'."\n";
			}
			if ($basics['list_divider']) {
				$divide = $row[$basics['list_divider']];
			}
		}
	}

	$r .= '</table>
	<br class="clr" />
	</div>
	<div class="descrR">'.$basics['descrR'].'</div>';
	//ScrollTo
	if ($_REQUEST['id']) {
		$r .= '
		<script type="text/javascript">
			$(document).ready(function(){;
				$("#fw-item_list").scrollTo($("tr.fw-eventA"),1000);
			});
			</script>
		';
	}
	return $r;
}

/**
 * clean all array and send header with values from database
 *
 * @param array $post
 * @param array $get
 * @param array $fields
 * @param array $basics
 * @return unknown
 *
 * Clean-> fields,basics
 */
function fw_data_clean_fields($post, $get, $fields, $basics){
	$form = 0;
	$cleanVar = fw_data_cleanup($fields, $basics);
	$fields  = $cleanVar[0];
	$basics  = $cleanVar[1];
	$err = 0;
	$enctype = '';
	if ($basics['files'] == 1) {
		$enctype = ' enctype="multipart/form-data"';
	}
	$r .= "\n".'<form method="post"'.$enctype.' action="'.FRAMEWORK_URL.$basics['op'].'"'.$basics['addon_submit'].'>'.$basics['form_addon'];
	//set option based on value of opt sent via GET
	if ($basics['opt']) {
		$post['opt'.$basics['opt']] = 1;
	}
	//check if user can remove / add item
	if ($basics['editonly'] == 1 && (isset($post['opt3']) || isset($post['opt4']))) {
		unset($post['opt3'], $post['opt4']);
	}
	//get values for choosen ID
	if ($basics['id']) {
		$fields = fw_data_get($fields, $basics);
	}
	if (isset($post['opt3'])) {
		if ($basics['id']) {
			$r .= '<input type="hidden" name="id" value="'.$basics['id'].'" />';
		}
		$r .= $basics['inf_del_query'].' ? <input type="button" value="'.INF_NO.'" class="submit" onclick="return go_back_page();"/> <input class="btn medium green awesome" type="submit" name="opt4" value="'.INF_YES.'">';
		//remove entry
	}
	if (isset($post['opt2']) || isset($post['opt1'])) {
		$status = fw_data_validate($basics, $fields, $post);
		if ($status[0] == 0) {
			unset($post['opt2']);
			unset($post['opt1']);
			if ($status[1]['req']) {
				$return_word = INF_REQUIRED.'('.implode(', ', $status[1]['req']).')';
				++$err;
			} else if ($status[1]['unique']) {
				$return_word = INF_UNIQUE.'('.implode(', ', $status[1]['unique']).')';
				++$err;
			} else if ($status[1]['other']) {
				$return_word = $status[1]['other'];
				++$err;
			} else if ($status[1]['file_ext']) {
				$return_word = str_replace('{items}', '('.implode(', ', $status[1]['file_ext']).')', INF_FILE);
				++$err;
			}
			$r .= $return_word;
		}
	}
	if ($post['opt12'] == 1) {
		gain_entities_sortable();
		exit;
	}
	if ($basics['single_field']) {
		foreach ($fields as $ky => $v) {
			if ($ky != $basics['single_field']) {
				unset($fields[$ky]);
			}
		}
	}
	if ($err > 0) {
		$form = 1;
	}
	return array($r, $post, $get, $fields, $basics, $form, $err, $return_word);
}

/* do all action add,update,delete */
function fw_action($post, $get, $fields, $basics){
	global $db, $config;
	$form = 0;
	$error = 0;

	//run update function
	//run remove function
	$funct = PREFIX.$_REQUEST['mod'];
	if ($_REQUEST['view']) {
		$funct .= '_'.$_REQUEST['view'];
	}
	$function_update .= $funct.'_update';
	$function_remove .= $funct.'_remove';

	//for add new record // run update function
	if (isset($post['opt1'])) {
		$addResult = fw_action_add($basics, $fields, $post);
		if ($addResult[0] == 1) {
			$r .= '<div class="fw-info_action">'.$basics['inf_add'].'</div>';
		}
		$basics['id'] = $addResult[1];
		//run function for submit
		if (function_exists($function_update)) {
			$function_update($basics['id']);
		}
	}

	//keep activity
	if ($basics['log_activity'] == 1) {
		//set error because we need to show text
		fw_log_user_activity($basics); //insert log to log_change table and return message
	}
	//ajax update
	if (isset($post['opt4']) || $_REQUEST['opt'] == 4) {
		//after click delete form
		//show question before entry remove
		if ($basics['log_removed'] == 2) {
			$db->Execute(fw_action_update($basics, $fields, $post), 'fw');
			//why we need log_removed == 2
		} else if (fw_action_remove($basics, $fields)) {
			$r .= '<div class="fw-info_action">'.$basics['inf_del'].'</div>';
		}
		if (function_exists($function_remove)) {
			$function_remove($basics['id']);
		}
		if (function_exists($function_update)) {
			$function_update($basics['id']);
		}
		if ($basics['actions']['manage_group']) {
			//remove
			$sql = SQL('DELETE FROM gain_fw_entity_group_item
			WHERE group_token IN(
				SELECT group_token FROM gain_fw_entity_group WHERE entity=%s AND removed IS NULL
			) AND group_id=%d', $basics['entity'], $basics['id']);
			$db->Execute($sql);
		}
		//run for update table fav&recent_page
		fw_update_primary_page('delete', $basics);
	} else if (isset($post['ajax_update']) || isset($post['opt2']) || ($_REQUEST['post_form'] && !isset($post['opt1']))) {//
		if ($db->Execute(fw_action_update($basics, $fields, $post), 'fw')) {
			//run function for submit
			if (function_exists($function_update)){
				$function_update($basics['id']);
				//run for update table fav&recent_page
				fw_update_primary_page('update', $basics);
			}
			if (isset($post['opt2'])) {
				$r .= '<div class="fw-info_action">'.$basics['inf_upd'].'</div>';
			}
		}
	}
	//TODO add content show error
	if ($basics['check_query']) {
		$check_id = $db->GetOne($basics['check_query'], 'fw');
		if ($check_id > 0 && !$_REQUEST['opt'] == 11) {
			$basics['id'] = $check_id;
		}
	}
	if ($_REQUEST['opt'] == 4 || $post['opt1'] || $post['opt2']) {
		if ($config['cacheTables']) {
			if (in_array($basics['table'], $config['cacheTables'])) {
				fw_cache($basics['table'], 1);
			}
		}
	}
	return array('content' => $r, 'id' => $basics['id'], 'error' => $error);
}

/**
 * call from data-definition
 * @param $post
 * @param $get
 * @param $fields
 * @param $basics
 * @param $typ
 * @return unknown_type
 */
function fw($post, $get, $fields, $basics, $typ = ''){
	global $db, $cache_user, $cm_menu;
	//set default settings & aliases
	$r 	= '';
	if ($basics['descrT'] != '' && $_REQUEST['fw_listing'] != 1) {
		$r .= $basics['descrT'];
	}
	$error = 0;
	//to recognize what information should be displayed
	$inf_data = fw_data_clean_fields($post, $get, $fields, $basics);
	$post 	 = $inf_data[1];
	$get 	 = $inf_data[2];
	$fields  = $inf_data[3];
	//set special fields?
	$sp_fields = PREFIX . 'special_fields';
	if (function_exists($sp_fields)) {
		$fields = $sp_fields($fields);
	}
	$basics  = $inf_data[4];

	if ($basics['single_item'] > 0) {
		$basics['id'] = $basics['single_item'];
	}
	if ($_REQUEST['fw_listing'] == 1) {
		$typ = 'list_all';
	}

	$basics['id'] = (int)$basics['id'];
	//show header
	if ($basics['editonly'] == 0) {
		$p = $basics['header'];
	}
	$form = 0;
	$list = 0;
	if ($typ == 'form' || $basics['single_item'] > 0 || $basics['single_field']) {//form only
		$form = 1;
	} else if ($typ == 'list') {//list only
		$list = 1;
	} else if ($typ == 'list_all') {//list all items
		$list = 3;
	} else if ($typ == 'slist') {//TODO special list WHY WE NEED IT ????
		$list = 2;
		//editonly: 0,1,2
		//2 can delete, cannot add new
		if ($basics['editonly'] == 0) {
			if ($basics['table']) {
				$p = '<a href="'.FRAMEWORK_URL.$basics['op'].'&amp;opt=10">'.$basics['header'].'<img alt="new" title="'.INF_NEW.'" src="'.FRAMEWORK_IMG.'new.png" /></a>';
			} else {
				$p = $basics['header'];
			}
		}
		$form = $inf_data[5];
	} else if ($typ == 'view_zone_form') {
		$form = 1;
	} else if ($typ == 'view_zone_detail') {
		$list = 4;
	} else if ($typ == 'table_list_js') { //send pattern form with js
		$list = 5;
	} else if ($typ == 'search_result') { //send pattern form with normal
		$list = 6;
	} else {//default view form + list
		$form = 1;
		$list = 1;
	}
	//set header_def for form and detail
	if ($typ == 'view_zone_form' || $typ == 'view_zone_detail') {
		if (array_key_exists('count_row_zero', $fields) || array_key_exists('item_removed', $fields)) {
			if ($_REQUEST['mod'] == 'settings' || $_REQUEST['mod'] == 'newsletter') {
				$redirect_linked = 'index.php?mod='.$_REQUEST['mod'].'&view='.$basics['entity'].'&re-act=0&search_for='.$basics['entity'];
			} else if ($_REQUEST['mod'] == $basics['entity']) {
				if ($cm_menu['M'][$basics['entity']]['M']) {
					$redirect_linked = 'index.php?mod='.$cm_menu['M'][$basics['entity']]['M'].'&re-act=0&search_for='.$basics['entity'];
				} else {
					$redirect_linked = 'index.php?mod='.$basics['entity'].'&re-act=0&search_for='.$basics['entity'];
				}
			}
			die("Location: ".$redirect_linked);
			exit;
		}

		if (!$basics['item_display'] || $basics['item_display'] == '') {
			$basics['item_display'] = fw_item_display($fields, $basics);		
		}

		if ($basics['item_display_add']) {
			$basics['item_display'] .= $basics['item_display_add'];
		}
		$basics['item_display'] = clean($basics['item_display']);

		if ($_REQUEST['link'] == 'add' || $_REQUEST['opt'] == 11) {
			$basics['pattern_replace']['header_def'] = msg('new '.$basics['entity']);
			$duplicate_notify_word = msg('duplicate_notify_word');
			if ($basics['hide_notify_duplicate'] != 1) {
				if ($_REQUEST['opt'] == 11) {
					$duplicate_notify_word = str_replace('{items}', '"'.$basics['item_display'].'"', $duplicate_notify_word);
					if (isset($_REQUEST['popup_id'])) {
						//<a onclick="show_popup_in_search(this,'clients&amp;view=quotations&amp;item_id=5232','197','edit',0);" href="#edit197"><img title="edit" src="im/edit.png"></a>
						$link = msg('click').' <a onclick="show_popup_in_search(this,\''.$_REQUEST['mod'].'&amp;view='.$_REQUEST['view'].'&amp;item_id='.$_REQUEST['item_id'].'\',\''.$basics['id'].'\',\'edit\',0);" href="#edit'.$basics['id'].'"><img title="edit" src="im/edit.png"></a>';
					} else {
						//link
						if ($basics['entity'] == $_REQUEST['mod']) {
							$duplicate_link = 'index.php?mod=' . $basics['entity'] . '&link=edit&id=' . $basics['id'];
						} else {
							$duplicate_link = 'index.php?mod=' . $_REQUEST['mod'] . '&view=' . $basics['entity'] . '&link=edit&id=' . $basics['id'];
						}
		
						$link = msg('click').' <a href="'.$duplicate_link.'"><img src="im/edit.png"/></a>';
					}
					$duplicate_notify_word = str_replace('{link}', $link, $duplicate_notify_word);
		
					$duplicate_notify = '<div style="padding: 0.7em; margin-top: 20px; margin-bottom: 10px;" class="ui-state-highlight ui-corner-all">
						<p><span style="float: left; margin-right: 0.3em;" class="ui-icon ui-icon-alert"></span>'.$duplicate_notify_word.'</p>
					</div>';
				}
			}
		} else {
			$basics['pattern_replace']['header_def'] = $basics['item_display'] . $basics['header_def_append'];// . ' <span>#'.$basics['id'].'</span>';
		}
		//set show options
		$verify_icon = '';
		if ($basics['id']) {
			$verify_icon = '';
			if ($basics['verify'] == 1) {
				if ($fields['verified']['default'] != '') {
					$verify_name = $cache_user[$fields['verified_by']['default']]['abbr'];
					$verify_icon = ' <img src="im/verify_p.png" class="entity_tool_box_icon" title="'.$verify_name.' - '.format_date($fields['verified']['default']).'"/>';
					$verify_notify = '';
				} else {
					$img_verify = '<img src="im/verify_n.png" class="entity_tool_box_icon" rel="click" title="'.msg('Please verify details of this '.$basics['entity']).'"/>';
					if (check_permission('verify', $basics['entity']) == 1) {
						$verify_icon = ' <a href="#verifyMe" onclick="gain_verify_item(this, \''.msg('confirm_verifiy_'.$basics['entity']).'\',\'mod=entities&entity='.$basics['entity'].'&id='.$basics['id'].'&view=verify\')">'.$img_verify.'</a>';

						$verify_notify = fw_notify_msg('verification_notify', 'error', array('class' => 'verification_notify'));
						$verify_notify = str_replace('{{entity}}', msg('entity_'.$basics['entity']), $verify_notify);
						$verify_icon_replace = $verify_icon;
						$verify_notify = str_replace('{{click_here}}', $verify_icon_replace, $verify_notify);
					} else {
						$verify_icon = $img_verify;
					}
					$verify_icon .= '
					<script type="text/javascript">
						$(document).ready(function(){
							$("div.show_options").css("border","2px solid #E78E8E").css("background","#FFF");
						});
					</script>';
				}
			}
		}

		if ($basics['verify'] == 1) {
			$basics['pattern_replace']['opt'] = str_replace('{{verify}}', '<span class="verify_item">'.$verify_icon.'</span>', $basics['pattern_replace']['opt']);
			$basics['pattern'] = str_replace('{{verification_notify}}', $verify_notify, $basics['pattern']);
		} else {
			$basics['pattern'] = str_replace('{{verification_notify}}', '', $basics['pattern']);
		}

		//START REPLACE FUNCTION
		if ($basics['pattern']) {
			$matches = array();
			preg_match_all('/{function(.*)}/Usi', $basics['pattern'], $matches);
			if ($matches) {
				foreach ($matches[0] as $k2 => $v2) {
					$param = array();
					$p = array();
					$p = explode('|', substr($v2,1,-1));
					//set another array for get data after get query,,, try to return values after get all data
					$fn = PREFIX.'plug_'.$p[1];
					//call function & //check function exist
					if (function_exists($fn)){
						$info = array('fields' => $fields, 'basics' => $basics);
						$n = array();
						for ($np = 2; $np < count($p); $np++) {
							$n = explode('=', $p[$np]);
							$param[$n[0]] = $n[1];
						}
						$val = $fn($param, $info);
						$basics['pattern'] = str_replace($matches[0][$k2], $val, $basics['pattern']);
					} else {
						$basics['pattern'] = str_replace($matches[0][$k2], $fn, $basics['pattern']);
					}
				}
			}
		}
		//END FUNCTON
	}

	//set page title
	if ($basics['set_page_title'] == 1 && $_REQUEST['mod'] == $basics['entity']) {
		if (strstr($_REQUEST['entity'], ',')) {
			$en = explode(',', $_REQUEST['entity']);
			$entity = 'menu_'.$en[0];
		} else {
			$entity = $basics['entity'];
		}
		fw_set_page_title($fields, $basics, msg($entity));
	}

	$cleanup_form = 0;
	//action to database for table
	//no error do update
	if ($inf_data[6] == 0) {
		$actions = fw_action($post, $get, $fields, $basics);
	}

	if ($_REQUEST['opt'] == 4) {
		if ($_REQUEST['ajax'] == 1) {
			if ($_REQUEST['submit_type'] != 'json') {
				if ($basics['refresh_action_ajax'] != '') {
					$refresh = '#'.$basics['refresh_action_ajax'];
				} else {
					$refresh = '#'.$basics['entity'].'_search_result';
				}

				if ($_REQUEST['search_for']) {
					echo '
					<script type="text/javascript">
						$(document).ready(function(){
							$("'.$refresh.'").load("index.php?ajax=1&mod='. $basics['op'] . '&re-act=' . $basics['id'] . '&act=4");
						});
					</script>
					';
				} else {
					echo '
					<script type="text/javascript">
						$(document).ready(function(){
							window.location.href = "index.php?mod='. $basics['op'] . '&entity=' . $basics['entity_key'] . '&re-act=' . $basics['id'] . '&act=4";
						});
					</script>
					';
				}
				exit;
			}
		} else {
			header('location:index.php?mod=' . $_REQUEST['mod']);
			exit;
		}
	}

	//ajax_update for single item
	if ($form == 1 || $_REQUEST['ajax_update'] || $_REQUEST['ajax'] == 1) {//run DB actions
		$basics['id'] = $actions['id'];
		if ($actions['id'] > 0 && !isset($post['opt5']) && !isset($post['opt10']) && isset($post['opt1'])) {
			$cleanup_form = 1;
			$form = 0;
		}

		$error_form = $inf_data[5];
		$message = addslashes($inf_data[7]);
		//check confirm data without error form
		if ($basics['log_change'] == 1 && $error_form == 0 && $actions['error'] == 1) {
			$message = addslashes($actions['content']);
		}
		$basics['actions_header'] = $inf_data[0] . $actions['content'];
		//return ajax submit request
		if ($_REQUEST['submit_type'] == 'json' && $_REQUEST['ajax'] == 1) {
			$del = 0;
			if ($_POST['opt4'] || $_REQUEST['opt'] == 4) {
				$del = 1;
			}
			$opt5 = 0;
			if (isset($_REQUEST['opt2']) || isset($_REQUEST['opt']) == 11) {
				$opt5 = 1;
			}
			$fw_load_entity = '';
			if ($_POST['fw_re-action']) {
				$_POST['fw_re-action'] = base64_decode($_POST['fw_re-action']);
				$fw_load_entity = str_replace('{id}', $basics['id'], $_POST['fw_re-action']);
				if ($del == 1) {
					$f_load = 4;
					$fw_load_entity = 'index.php?mod=';
					$mod_main = gain_entity_get_entity_detail($basics['entity'], 'mod_main');
					if ($mod_main != '') {
						$fw_load_entity .= $mod_main;
					} else {
						$fw_load_entity .= $basics['entity'];
					}
				} else {
					$f_load = $opt5;
				}

				$fw_load_entity .= '*';
				$fw_load_entity = str_replace('*', '&search_for='.$entity.'&re-act='.$basics['id'].'&act='.$f_load, $fw_load_entity);
// 				$fw_load_entity = str_replace('*', '&re-act='.$basics['id'].'&act='.$f_load, $fw_load_entity);
				$matches2 = array();
				preg_match_all('/{{(.*)}}/Usi', $fw_load_entity, $matches2);
				if ($matches2) {
					foreach ($matches2[1] as $k => $v) {
						$v_cleaned = str_replace('^', '', $v);
						if ($_POST[$v_cleaned]) {
							if ($v{0} != '^') {
								$replace_me = '&'.$v_cleaned.'='.$_POST[$v_cleaned];
							} else {
								$replace_me = $_POST[$v_cleaned];
							}
						} else {
							$replace_me = '';
						}
						$fw_load_entity = str_replace($matches2[0][$k], $replace_me, $fw_load_entity);
					}
				}
			}
			echo '{"error":"'.$error_form.'", "message":"'.$message.'", "del":"'.$del.'", "id":"'.$basics['id'].'", "opt5":"'.$opt5.'", "fw_load_entity":"'.$fw_load_entity.'"}';
			exit;
		}
	}
	//set show from after action???
	if ($post['opt4'] || $post['opt3'] || ($_POST['post_form'] && $inf_data[5] == 0)) {
		$form = 0;
	}

	if ($_REQUEST['fw_listing'] != 1) {//dont show header when we show listing
		if ($post['opt10'] || $post['opt11'] || !$basics['id'] || $post['opt1']) {
			$p = $p;
		} else if ($post['opt5'] || $post['opt2'] || $post['opt3'] || $post['opt4']) {
			$p = $basics['header_edit'];
		} else {
			$p = ' ';
		}
		$r .= fw_layout_head($p);
		if ($basics['actions_header']) {
			$r .= $basics['actions_header'];
		}
	}

	if ($form == 1) {
		//display form
		if (($typ == 0) || isset($post['opt11']) || isset($post['opt5']) || isset($post['opt10']) || $basics['single_item'] > 0 || (!isset($post['opt1']) && !isset($post['opt2']) && !isset($post['opt3']) && !isset($post['opt4']) && !isset($post['opt6']))) {
			if ($typ == 'view_zone_form') {
				$z = $basics['content'] . $basics['pattern'];
				//automatic default
				$matches_zone = array();
				preg_match_all('/{{zone_(.*)}}/Usi', $z, $matches_zone);
				if ($matches_zone) {
					$basics['view_zone'] = count($matches_zone[0]);
					$fld = fw_form($basics, $fields, $post);
					//add options add/save/delete
					$z = str_replace('{{options}}', $fld['options'], $z);
					//add open form tag
					$z = str_replace('{{open_tag_form}}', $basics['actions_header'], $z);

					foreach ($matches_zone[0] as $k => $i) {
						if (strstr($i, 'notable')) {//do not add additional table for field
							$z = str_replace($i, $fld['form'][$matches_zone[1][$k]], $z);
						} else {
							$z = str_replace($i, '<table cellspacing="1" cellpadding="3" class="fw-display_item" width="100%">' . $fld['form'][$matches_zone[1][$k]] . '</table>', $z);
						}
					}

					//replace with custom pattern
					if ($basics['pattern_replace']){//can define from data_difination function
						foreach ($basics['pattern_replace'] as $k => $v) {
							$z = str_replace('{{'.$k.'}}', $v, $z);
						}
					}

					//replace with field values
					foreach ($fields as $k => $v) {
						$z = str_replace('{{field_'.$k.'}}', $v['default'], $z);
					}
					//TODO beem
					$r = $z;
				} else {
					$r .= 'need to define num of view_zone';
				}
			} else {
				$fld = fw_form($basics, $fields, $post);
				$r .= $fld;//normal form
			}
		}
		//set hidden fields for edit item
		if ($basics['id']) {
			$set_id = '<input type="hidden" name="id" value="'.$basics['id'].'" />';
			$r .= $set_id;
			$fld .= $set_id;
		}
		$r .= '</form>
';
		//option for date calendar
		if ($_REQUEST['link'] == 'add' || $_REQUEST['link'] == 'edit' || $form == 1) {//remove request link
			$form_id = 'ajax_form_'.$basics['entity'];
			$r .= '
			<script type="text/javascript">
				$(document).ready(function(){'."\n";
					if ($_REQUEST['ajax'] == 1 && !isset($_REQUEST['popup_id'])) {
						$r .= 'gain_init("form#'.$form_id.'");';
					}
					if (WYM == 1) {
						$r .= '
						jQuery(".wymeditor").wymeditor({
							postInit: function(wym){
								wym.html(wymData[wym._index]);
							}
						});
						';
					}
					$r .= '
				});
			</script>';
		}
		//option for text editor
		if ($basics['descrL']) {
			$r .= '<br />'.$basics['descrL'];
		}
		if ($basics['single_field']) {
			return array('content' => '<form method="post" id="ajax_form" action="index.php?ajax=1&amp;mod='.$_REQUEST['mod'].'&amp;view='.$_REQUEST['view'].'">'.$fld.'<input type="hidden" name="edit_field" value="'.$_REQUEST['edit_field'].'"/><input type="hidden" name="ajax_update" value="1"/><input type="submit" name="submit" value="&raquo;&raquo;" class="submit"/></form>
			<script type="text/javascript">
				$("#ajax_form").ajaxForm({
					dataType: "json",
					success:  processJson
				});
				function processJson(data){
					$("#ajax_form").parent().html(data.message);
				}
			</script>');
		}
	}

	//$re_act = gain_entities_show_re_act($basics['entity'], 1);
	if ($list == 1) {
		$r .= '</td><td valign="top">'.$basics['descrTR'];
		$query_list = $basics['list_query'];
		//search form
		if ($basics['search_form'] == 1) {
			$search_inf = fw_list_search($post, $get, $fields, $basics);
			$r .= $search_inf[0];
			if ($search_inf[1]) {
				if (strpos($query_list,'WHERE')<0) {
					$query_list .= ' WHERE '.substr($search_inf[1], 5);
				} else {
					$query_list .= $search_inf[1];
				}
			}
		}
		if ($basics['log_removed'] == 1) {//hide items marked as removed
			if (strpos($query_list,'WHERE') == '') {
				$query_list .= ' WHERE (removed_by IS NULL OR removed_by=0)';
			} else {
				$query_list .= ' AND (removed_by IS NULL OR removed_by=0)';
			}
		}
		if ($basics['positions'] == 1) {//add position first of all
			if ($basics['list_query_add'] != '') {
				$query_list .= $basics['list_query_add'].', positions';
			} else {
				$query_list .= ' ORDER BY positions';
			}
		} else {
			$query_list .= $basics['list_query_add'];
		}
		$class = '';
		if ($basics['list_size']) {//set size of the list
			$lStyle = explode(':', $basics['list_size']);
			$basics['table_height'] = $lStyle[1];
			$class = ' id="fw-item_ist" style="width: '.$lStyle[0].'px; height: '.$lStyle[1].'px; overflow: auto; display: block;"';
			$basics['list_size_width'] = ' style="width: '.($lStyle[0]-20).'px;"';
		}
		$r .= "\n".'
		<div class="fw-form_list_header"'.$basics['list_size_width'].'>
			<div class="fleft">'.$basics['descrTRO'];
		if ($basics['editonly'] == 0) {
			$r .= '<a href="'.FRAMEWORK_URL.$basics['op'].'&amp;opt=10"><img alt="new" title="'.INF_NEW.'" src="'.FRAMEWORK_IMG.'add.png" /></a> ';
		}
		if ($basics['listing'] == 1) {
			$r .= '<a target="_blank" href="'.FRAMEWORK_URL.$basics['op'].'&amp;ajax=1&amp;fw_listing=1">'.INF_LISTING_ALL.'</a>';
		}
		$r .= ' &nbsp; <span></span></div>
			<div class="fright">'.$basics['header_list'].'</div>
		</div><br class="clr"/>
		<div'.$class.'>
		<script type="text/javascript">
		$(document).ready(function(){
			$("div.fw-form_list_header img").mouseover(function(){
				$(this).parents("div.fw-form_list_header").children("div").children("span").html($(this).attr("title"));
			}).mouseout(function(){
				$(this).parents("div.fw-form_list_header").children("div").children("span").html("");
			});
		});
		</script>
		';
		$r .= fw_list($query_list, $basics);
		//$r .= "</div>";
		$r .= $basics['listing_add'];
	} else if ($list == 2) {//plain list of items
		$r .= fw_entity_list($basics);
	} else if ($list == 3) {//list all items, later we can use it with xls export
		$r = fw_list_export($basics, $fields);
	} else if ($list == 4) {//view_zone
		$z = $basics['pattern'];
		$z = str_replace('{{options}}', '', $basics['pattern']);
		//automatic default
		$matches_zone = array();
		preg_match_all('/{{zone_(.*)}}/Usi', $z, $matches_zone);
		if ($matches_zone) {
			$basics['view_zone'] = count($matches_zone[0]);
			//how many zone need to replace
			foreach ($matches_zone[0] as $k => $i) {
				$return_zone = fw_form_zone($matches_zone[1][$k], $fields, $basics,2);
				//replace table class
				$z = str_replace('{{zone_no}}', ' class="zone_'.$matches_zone[1][$k].'"', $z);
				$z = str_replace($i, $return_zone['result'], $z);
				$fields_values = $return_zone['fields'];
			}
		}

		//replace with custom pattern
		if ($basics['pattern_replace']) {//can define from data_difination function
			foreach ($basics['pattern_replace'] as $k => $v) {
				$z = str_replace('{{'.$k.'}}', $v, $z);
			}
		}
		if ($fields_values) {
			//replace with field values
			foreach ($fields_values as $k => $v) {
				$z = str_replace('{{field_'.$k.'}}', $v['default'], $z);
			}
		}

		$r = $z .
		'<script type="text/javascript">
			$(document).ready(function(){
				$("table.fw-display_item").each(function(m,n){
					var tab_id = $(n).attr("id");
					var sub_content_size = 0;
					sub_content_size = $("table#"+tab_id+" tr.fw-form_item").size();
					if (sub_content_size == 0) {
						$("table#"+tab_id).remove();
					}
				});
			});
		</script>'.$basics['listing_add'];
	} else if ($list == 5) {//table_list_js
		//define table array
		$r .= fw_list_js($basics);
	} else if ($list == 6) {//search_result
		$t = fw_entity_list($basics);
		if ($basics['content_under_table']) {
			$t .= '<div style="padding-top: 10px;">'.$basics['content_under_table'].'</div>';
		}
		return $re_act . $t;
	}
	//add foter to page if its not listing
	if ($_REQUEST['fw_listing'] != 1 && !$basics['view_zone']) {
		$r .= fw_layout_foot($basics['descrM']);
	}

	if ($basics['output'] == 'F') {//if we want to return information in array not all in one
		$return['content'] = $r;
		$return['id'] = $basics['id'];
		$return['error'] = $inf_data[5];
	} else {
		$return = $r;
	}
	return $re_act . $duplicate_notify . $return;
}

/**
 *
 * @param $zone
 * @param $fields
 * @param $basics
 * @param $typ
 * @return zone pattern
 */
function fw_form_zone($zone, $fields, $basics, $typ = 1){
	if ($typ == 1) {//this type need to clean before do anything again
		//clean and get all values
		$cleanVar = fw_data_cleanup($fields,$basics);
		$fields  = $cleanVar[0];
		$basics  = $cleanVar[1];
		$fields  = fw_data_get($fields,$basics);
	}//other type no need to clean OR get data for basics/fields again
	//set table

	$r = '';
	if (strstr($zone, 'notable')) {
		$r .= '<div class="fw-display_item" id="'.$basics['table'].'_z'.$zone.'">';
	} else {
		$r .= '<table cellspacing="1" cellpadding="4" class="fw-display_item" id="'.$basics['table'].'_z'.$zone.'">';
	}
	$x = 0;
	$y = 0;
	foreach ($fields as $ky => $vl) {
		//check value only zone that want to show
		if ($vl['zone'] == $zone) {
			$vl['displayonly'] = 1; //this setting will return just value[ == $f['field'] == ]
			//set for group action
			if ($vl['type'] == 'head') {
				$check_head[$ky] = 1;
			}
			if ($vl['group']) {
				if (is_array($vl['default'])) {
					$def = implode($vl['default'], '');
				} else {
					$def = $vl['default'];
				}
				$check_group[$vl['group']] .= $def;
			}
			if (!$vl['primary_field']) {
				$f = fw_form_item($ky, $vl , $basics);
				if ($vl['type'] == 'head' || trim($f['field'])) {
					$r .= $f['head'] . $f['field'] . $f['foot'];
				}
			}
		}
	}
	if (strstr($zone, 'notable')) {
		$r .= "\n".'</div>'."\n";
	} else {
		$r .= "\n".'</table>'."\n";
	}

	if ($check_head) {
		foreach ($check_head as $key_head => $val) {
			if (isset($check_group[$key_head])) {
				$rep['{{pattern_group_'.$key_head.'}}'] = '';
				if (trim($check_group[$key_head]) == '') {
					$r = '';
				}
				$r = str_replace(array_keys($rep), array_values($rep), $r);
			} else {
				$rep['{{pattern_group_'.$key_head.'}}'] = '';
				$rep['{{group_hide_'.$key_head.'}}'] = '';
				$r = str_replace(array_keys($rep), array_values($rep), $r);
			}
		}
	}

	return array('result' => $r, 'fields' => $fields);
}

//TODO use?
/**
 *
 * @param $fields
 * @param $basics
 * @return unknown_type
 */
function fw_list_search($fields, $basics){
	//1.read pattern and get all search fields
	$key = '';
	$a = array();

	//2 clean fields and basics values
	$cleanVar = fw_data_cleanup($fields, $basics);
	$fields  = $cleanVar[0];
	$basics  = $cleanVar[1];

	//get form for search
	$pattern_search = $basics['pattern'];

	//3.check it is search fields
	$pattern = '{([A-Za-z0-9-_]+)}';
	preg_match_all($pattern, $pattern_search, $matches);
	if (is_array($fields)) {
		foreach ($matches[0] as $k => $val) {
			if (strstr($val,'_search')) {
				$key = substr_replace($val,'',-7);
				//4.check array key exits
				if (array_key_exists($key, $fields)) {
					$s_fields[$key] = $fields[$key];
				}
			}
		}
	}

	//5.do search from by $s_fields
	// generate query ..by type of fields
	foreach ($s_fields as $k => $v) {
		//if type-T change it to [type-I] or set empty
		if ($v['type'] == 'T') {
			$v['type'] = 'I';
			unset($v['param2']);
		}
		//set widht&height for input fields [param is set by $basics]
		if ($v['type'] == 'I') $v['param1'] = $basics['input_w'];
		//if ($v['type'] == 'R') $v['type'] = 'S';

		if ($_REQUEST[$k] != '') {
			//6.TODO add linked ...
			if ($v['search'] == 1) {
				$r['linked'] .= '&amp;'.$k.'='.$_REQUEST[$k];
				switch($v['type']) {
					case 'R':
					case 'S': $r['sql_search'] .= ' AND '.$k.'="'.$_REQUEST[$k].'"'; break;
					case 'I': $r['sql_search'] .= ' AND '.$k.' LIKE "%'.$_REQUEST[$k].'%"'; break;
				}
			}

			//set default for show values after click search
			$v['default'] = $_REQUEST[$k];
		}

		$a = fw_form_item($k,$v,$basics);
		$box_forms[$k.'_search'] = $a['field'];
	}

	$r['form'] .= '<div id="fw-search_form1"><form k="'.FRAMEWORK_URL.$_REQUEST['op'].'" method="post">';
	$txt = $pattern_search;
	foreach ($box_forms as $ka => $va) {
		$txt = str_replace('{'.$ka.'}',$va,$txt);
	}

	$txt = str_replace('{search_button}','<input type="submit" class="search_button" value="search" name="search" />',$txt);
	$txt = str_replace('{clear_button}','<input type="button" class="submit clear" value="clear"/>',$txt);
	$r['form'] .= $txt;
	$r['form'] .= '</div>
	<script type="text/javascript">
		$(document).ready(function(){
			$("input.clear").click(function(){
				window.location.href = "'.FRAMEWORK_URL.$_REQUEST['op'].'";
			});
		});
	</script>
	';
	return $r;
}

//TODO add function strtolower for header fields
/**
 *
 * @param $key
 * @param $inf
 * @param $basics
 * @return unknown_type
 */
function fw_form_item($key, $inf, $basics){
	$r['field'] = '';
	$r['head'] = '';
	$r['foot'] = '';
	$title = '';
	$titleadd = '';
	$field_id = '';
	$file = '';
	$inf['id'] = $basics['id'];

	//get array values and type
	//TODO revise this functionality, add some comments
	if ($inf['values'] && $inf['type'] != 'date' && ($inf['type'] != 'select' && $inf['param2'] != 'N')) {
		if (!is_array($inf['values'])) {
			$getInfo = getArray($inf['values']);
			if ($inf['type'] != 'file') {
				if ($getInfo[1] != 'X' && !empty($getInfo[1])) {
					$inf['param2'] = $getInfo[1];
				}
				//if array type is not set then its ASSOC by default
				if (!$inf['param2']) {
					$inf['param2'] = 'A';
				}
			}
			$inf['values'] = $getInfo[0];
		}
	}

	if ($inf['group']) {
		$class_group = ' group_'.$inf['group'].'{{group_hide_'.$inf['group'].'}}';
	}

	//TODO add functionality for parameter show
	$class = 'fw-form_head';
	if ($inf['req'] && !$inf['displayonly']) {
		$class .= '_r';
	}
	if ($inf['type'] == 'pattern_multi') {
		$class .= ' fw-event2';
	}
	//create link for file
	if ($inf['type'] == 'file') {
		if (!is_array($inf['param2']) && $inf['default']) {
			$file .= form_file_preview($key, $basics, $inf);
		} else if (isset($inf['default']['file'])) {
			if ($inf['param2']['name'] == 'E') {
				$link = $inf['param2']['bigl'].$basics['id'].'.'.$inf['default']['file'];
			} else if ($inf['param2']['name'] == 'N') {
				$link = $inf['param2']['bigl'].$basics['id'].'_'.$key.'.'.$inf['default']['file'];
			} else if ($inf['param2']['name'] == 'F') { //set fields
				$link = $inf['param2']['bigl'].$inf['default']['fields'].'.'.$inf['default']['file'];
			} else {
				$link = $inf['param2']['bigl'].$inf['default']['file'];
			}
			if ($inf['param2']['mini'] > 0) {
				$link2 = $inf['param2']['smll'].$inf['default']['file'];
				if (is_file($link2)) {
					$file = ' <a target="_blank" href="'.$link2.'"><img src="'.FRAMEWORK_IMG.'file2.gif" /></a>';
				}
			}
			if (is_file($link)) {
				$img_ext = array('jpg', 'jpeg', 'png', 'bmp', 'gif');
				if (in_array($inf['default']['file'], $img_ext)) {
					$file_pic = FRAMEWORK_IMG.'picture.gif';
				} else {
					$file_pic = FRAMEWORK_IMG.'file_download.png';
				}
				$file .= ' <a target="_blank" href="'.$link.'"><img src="'.$file_pic.'" /></a>';
			}
		}
	}

	//if we want only value then we dont need to mess with headers
	if ($inf['value_only'] != 1) {
		if ($inf['descr']) {
			$titleadd = '<span class="fw-silver">?</span>';
			$title = ' title="'.$inf['descr'].'"';
		}

		//to set plus button for multi fields
		if (is_array($inf['multi']) && $inf['displayonly'] != 1) {
			if ($inf['type'] != 'checkbox') {
				if ($inf['type'] != 'M' && $_REQUEST['link'] != 'detail') {
					$field_id = ' id="field_'.$key.'"';
					$add = '<img class="fw-point" src="'.FRAMEWORK_IMG.'new.png" title="'.msg('add ' . $key).'" onClick="replicate_add_item(\'field_'.$key.'\')"/>';
				}
			}
		}

		$display_file = '';
		if ($inf['displayonly'] != 1) {
			$display_file = $file;
		}
	}

	//to set style header for each rows
	if ($inf['type'] == 'head') {
		$addClass = '';
		if ($inf['param1']) {
			$addClass = '_'.$inf['param1'];
		}
		//foreach field check if empty or == vhead
		$r['head'] = '<tr class="fw-event2'.$addClass.'"><td colspan="2"'.$title.'>{{pattern_group_'.$key.'}}'.$titleadd.$inf['head'].$inf['append'].'</td></tr>';
	} else {
		//dont mess with headers when you want just value
		if ($inf['value_only'] != 1) {
			if ($inf['group']) {
				$class_group = ' group_'.$inf['group'].'{{group_hide_'.$inf['group'].'}}';
			}
			$semi = ': ';
			if ($inf['head'] == '') {
				$semi = '';
			}
			if ($inf['show'] == '2') {
				$r['head'] = '<td class="fw-formListHead"'.$title.'>'.$titleadd.$inf['head'].'</td>';
				$r['field'] = '<td'.$field_id.'>';
			} else if ($inf['show'] == '1') {
				$r['head'] = '<tr class="fw-form_item'.$class_group.'"><td class="'.$class.'"'.$title.'>'.$titleadd.$inf['head'].$display_file.$semi.$add.'</td><td'.$field_id.' class="fw-min_width">';
			} else if ($inf['show'] == '3') {
				$r['head'] = '<tr class="fw-form_item'.$class_group.'"><td colspan="2" class="'.$class.'"'.$title.$field_id.'>'.$titleadd.$inf['head'].$display_file.$semi.$add.'</td></tr><tr class="fw-form_item'.$class_group.'"><td colspan="2" '.$field_id.' class="fw-min_width">';
			} else if ($inf['show'] == '4') {
				$r['head'] = '<span class="bold"'.$title.$field_id.'>'.$inf['head'].'</span>';
				//for E-special form [type]
			} else if ($inf['show'] == '5') {
				$r['head'] = '<tr class="fw-form_item'.$class_group.'"><td colspan="2" '.$field_id.'>';
			} else if ($inf['show'] == '6') {
				$r['head'] = '<tr class="fw-form_item'.$class_group.'"><td class="fw-form_head"'.$title.' valign="top">'.$titleadd.$inf['head'].$semi.'</td><td>';
			} elseif ($inf['show'] == '7') {
				$r['head'] = '<tr class="fw-form_item'.$class_group.'"><td colspan="2" class="'.$class.'"'.$title.$field_id.'>'.$titleadd.$inf['head'].$display_file.$semi.$add.'</td></tr><tr class="fw-form_item'.$class_group.'"><td width="250" colspan="2" '.$field_id.' class="fw-min_width">';
			} elseif ($inf['show'] == '8') {
				$r['head'] = '<tr class="fw-form_item'.$class_group.'"><td colspan="2" class="'.$class.'"'.$title.$field_id.'>'.$titleadd.$inf['head'].$display_file.$semi.$add;
			}
		}
		if ($basics['show_tab'] == 1) {
			$r['head'] = '<tr class="fw-form_item"><td class="fw-min_width">';
		}
		$rf = '';
		//if we want to have only value then we can automaticaly set displayonly
		//if ($basics['displayonly'] == 1) $inf['value_only'] = 1;
		if ($inf['value_only'] == 1 || $basics['displayonly'] == 1) {
			$inf['displayonly'] = 1;
		}
		//act: validate, show, update
		//check if it not special fields
		if ($inf['type'] != 'E' && $inf['type'] != 'EF' && $inf['type'] != 'EM' && $inf['type'] != 'SP') {
			$cf_name = 'form_'.$inf['type'];
			if (function_exists($cf_name)) {
				if ($inf['type'] == 'file') {
					$rf = $cf_name($key, $inf, $link);//param not same , add action param
				} else {
					$rf = $cf_name($key, $inf);
				}
			} else {
				$rf = $cf_name.'...';
			}
		} else {// for special field
			switch($inf['type']) {
				case 'E': {
					$cf_name = PREFIX.$key;
					if (function_exists($cf_name)) {
						$rf = $cf_name($inf, 'display', $basics['id']);
					} else {
						$rf = $cf_name.'...';
					}
				} break;
				case 'EF': {
					//TODO modify custom function name
					$ke = explode("+", $key);
					$cf_name = PREFIX.$_REQUEST['mod'].'_'.$_REQUEST['view'].'_'.$ke[0];
					if (function_exists($cf_name)) {
						$rf = $cf_name($inf, 'display', $ke[1]);
					} else {
						$rf = $cf_name.'...';
					}
				} break;
				case 'EM': $rf = form_E_multi($key, $inf); break;//TODO recheck this function
				case 'SP': {// for speacial fields
					$cf_name = PREFIX.$key;
					if (function_exists($cf_name)) {
						$rf = $cf_name($inf, 'display', $basics['id']);
					} else {
						$rf = $cf_name.'...';
					}
				} break;
			}
		}
		if ($inf['value_only'] == 1 || $basics['single_field']) {
			return $rf;
		}
		//check empty data [don't show it]
		if ($rf == '') {
			$r = '';
		} else {
			$r['field'] .= $rf.$inf['addon'];
			if ($inf['show'] == 2 || $inf['show'] == 5) {
				$r['field'] .= '</td>'."\n";
			}
			if ($inf['show'] == 1 || $inf['show'] == 3) {
				$r['foot'] = '</td></tr>'."\n";
			}
		}
	}
	return $r;
}

//need other function for return an number (show icon for approve)
//what's happen? if have more than one person need to edit the data same time
//(select changes record and show forms)
function fw_log_user_activity($basics, $description = '', $typ = ''){
	global $db;
	//do log modify data
	//get value from database
	//$fields = fw_data_get($fields,$basics);
	//check value form post and ...

	if ($typ == '') {
		//check option (delete,add,edit)
		if (isset($_REQUEST['opt1'])) {
			$typ = 'add';
		}
		if (isset($_REQUEST['opt4']) || $_REQUEST['opt'] == 4) {
			$typ = 'remove';
		}
		if (isset($_REQUEST['opt2'])) {
			$typ = 'updated';
		}
		if ($basics['activity_type']) {
			$typ = $basics['activity_type'];
		}
	}

	if ($typ) {
		$param_qry = array(
			'table' => 'gain_fw_user_activity',
			'cols' => array(
				'entity', '%s', $basics['entity'],
				'entity_id', '%d', $basics['id'],

				'action', '%s', $typ,

				'description', '%s', $description,

				'action_date', '', 'NOW()',
				'action_by', '%d', $_SESSION[SESSION_L],

				'added', '', 'NOW()',
				'added_by', '%d', $_SESSION[SESSION_L],
				'updated', '', 'NOW()',
				'updated_by', '%d', $_SESSION[SESSION_L],
			),
		);
		db_query($param_qry);
	}
}
?>